コマンドプロンプトPHP
ローカルファイルの操作を行うのに何かしらプログラムでやらせたい事がありまして、かといってC#のVisualStudioでWindowsプログラムを組むほどでもない程度の作業があって、それを何の開発言語で書こうかな、と。
古い記憶を頼りに調べたら、Webサーバー向けの開発言語であるPHPでもWindowsのローカル上で動くことがわかり、簡単なプログラムを動作させてみました。
PHPならコンパイルも不要で、エディターで条件や対象フォルダ等を書き換えてすぐに再実行出来るので、今回の
ちょっとしたローカルファイルの操作
みたいな作業にはうってつけかな、と。
今日はそんなPHPコードを書いてみようかと。
テキストファイル
多数のテキストファイルがある中から、キーワードに一致した内容を取得したいとします。
今回は本文と中に「送料●●円」と書かれたテキストファイルから、送料の数値に該当する「●●」部分を抽出してみたいと思います。
テキストファイルは下記の様な感じ。
ファイル名の拡張子が「.txt」のファイルだけから読み取りたいとします。
簡単なプログラム設計
たかだか自分の作業を簡単に代行してくれるだけのツールの位置づけなので、ざっくり設計して終わりにしたいと思います。
【プログラム設計】
- 指定フォルダから、ファイル一覧を取得し、対象となる拡張子のファイルのみを処理対象とする
- 対象ファイルをループで1件ずつ処理する
- ファイル内の情報を全て文字列として受け取る
- 該当するキーワードの前後の文字列を検索し、間に存在するキーワードを抽出する
- 抽出したデータをcsvファイルとして出力する
ざっくりですが、まぁこんな所で。
コーディング
プログラム設計に沿ったコードを少々解説してみようかと。
1.指定フォルダから、ファイル一覧を取得し、対象となる拡張子のファイルのみを処理対象とする
指定フォルダは所詮自分のローカルフォルダなので、都度書き換える事とし定数宣言にしました。
対象ファイルの拡張子は今回は「.txt」を含むものを処理したいと思います。
<? const DIR = "F:/work"; const FIND_EXT = ".txt"; if (file_exists(DIR)) { $scanDirs = scandir(DIR); if ($scanDirs !== false) { foreach ($scanDirs as $scanDir) { if (is_file(DIR."/".$scanDir) && strpos($scanDir, FIND_EXT) !== false) { } } } } ?>
scandir()関数で対象フォルダの中のファイル一覧を取得します。
フォルダが含まれる場合にフォルダ名も取得してしまうので、is_file()関数でファイルだけを対象とします。
また拡張子が含まれるかどうかをstrpos()関数で文字列判定してみました。
2.対象ファイルをループで1件ずつ処理する
あ、上記のソースで既にループで処理しています(^-^;
foreach ($scanDirs as $scanDir)
の部分ですね。
3.ファイル内の情報を全て文字列として受け取る
file_get_contents()関数でファイル内データを全て文字列形式で受け取ります。
今回はテキストファイルが対象なので、細かい指定はしていません。
<? // ファイルを開く $fileRead = file_get_contents(DIR."/".$scanDir); ?>
4.該当するキーワードの前後の文字列を検索し、間に存在するキーワードを抽出する
キーワード前後の文字列を定数で指定して、ファイル内文字列を検索します。
日本語も含まれる文字列なのでバイト数ではなくて文字数で処理してくれるmb_strpos()関数や、mb_strlen()関数、mb_substr()関数を使用します。
<? const KEYWORD_STA = '送料'; const KEYWORD_END = '円'; $item = ""; // 初期化 $csvText = ""; // キーワード取得 $keyS = mb_strpos($fileRead, KEYWORD_STA) + mb_strlen(KEYWORD_STA); $keyE = mb_strpos(mb_substr($fileRead, $keyS), KEYWORD_END); $csvText = $csvText.trim(mb_substr($fileRead, $keyS, $keyE, "UTF-8")); $item = $item.$csvText."\n"; ?>
キーワード抽出前後のキーワードに挟まれた文字列を抜粋するために、キーワード開始位置と、キーワード終了文字数を取得し、抽出します。
5.抽出したデータをcsvファイルとして出力する
csv並びに加工した文字列をfopen()関数、fwrite()関数、fclose()関数を使って書きこみます。
<? $csvFileName = "Keyword"; $csvFileExt = ".csv"; $f = fopen($csvFileName.$csvFileExt, "wb"); fwrite($f, $item); fclose($f); ?>
全ソース
個別に見てきたソースコードをくっつけると下記の様になります。
<? const DIR = "F:/work"; const FIND_EXT = ".txt"; const KEYWORD_STA = '送料'; const KEYWORD_END = '円'; $csvFileName = "Keyword"; $csvFileExt = ".csv"; $item = ""; echo "GetKeyword Start".PHP_EOL; if (file_exists(DIR)) { $scanDirs = scandir(DIR); if ($scanDirs !== false) { foreach ($scanDirs as $scanDir) { if (is_file(DIR."/".$scanDir) && strpos($scanDir, FIND_EXT) !== false) { // ファイルを開く $fileRead = file_get_contents(DIR."/".$scanDir); // 初期化 $csvText = ""; // キーワード取得 $keyS = mb_strpos($fileRead, KEYWORD_STA) + mb_strlen(KEYWORD_STA); $keyE = mb_strpos(mb_substr($fileRead, $keyS), KEYWORD_END); $csvText = $csvText.trim(mb_substr($fileRead, $keyS, $keyE, "UTF-8")); $item = $item.$csvText."\n"; } } } } $f = fopen($csvFileName.$csvFileExt, "wb"); fwrite($f, $item); fclose($f); echo "GetKeyword End"; ?>
そして実際にphpファイルをコマンドプロンプトで実行すると下記の様になります。
開始と終了の通知だけ吐き出しました。
また対象フォルダ内には作成したcsvファイルが出力されています。
「Keyword.csv」というファイルが対象ファイルです。
結果は下記の様に。
500
750
1,000
2,000
1,234
987
「送料●●円」と書かれたテキストファイルの、送料の数値に該当する「●●」部分を抽出してCSVファイルとして出力する事が出来ました(^-^)v
キーワードの組み合わせを追加すれば、複数のキーワードを抽出する事が出来ますので、私の要件は満たしたので、これで良しとしたいと思います。
え?
ソースコードが汚い!?
自分向けのツールなのでお許しをば(^-^;