記事の概要
下記の方向けの記事になります。
- テキストファイル(.txt .csv .log .md等)に該当の文字が含まれているか検索を行いたい。
- ヒットした文字がどのファイルの何行目にあるか知りたい。
- フォルダの配下にあるすべてのテキストファイルから検索を行いたい。
必要な環境
- Windows10以降のOS
- OSの標準機能のみ(新規インストール作業等は不要)
記事の内容
今回は、PowerShell_ISEを利用したテキストファイル内の検索(Grep)について話そうと思うよ。
PowerShellってそんなことまでできるんですね。でも、複数ファイルの文字検索って、サクラエディタやVSCodeとかでもできますよね?なんでわざわざPowerShellを使うんですか?
その通りなんだけどさ(笑)なんらかの事情でソフトをインストールできない環境だったり、インストール権限のないスタッフが検索したい場合に便利かなと思って、中の人が作成したらしいから説明してほしいとのことだよ。
そうなんですね…少しめんどくさいですけど、聞きますね。
はい…
冗談ですよ!やりましょう(笑)
PowerShell_ISEを使用して文字検索を行う方法
では、気を取り直して…この検索方法はPowerShell_ISEを使用するんだ。PowerShell_ISEがわからない人は、先にこちらの記事で概要をつかんでみてね。
わかりました。
文字検索用スクリプトの作成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# === # 検索フォルダの場所。 cd c:\test_grep # ファイル名(あいまい検索は*を使用) $fileName = "grep*" # 拡張子(あいまい検索は*を使用) $extension = "txt" # 検索結果該当行から何行前まで表示するか。 $startRow = 1 # 検索結果該当行から何行後まで表示するか。 $endRow = 2 # 検索文字 $searchStr = "5行" # 出力結果を保存する場所。 $outFile = "c:\test_results\grep_results.txt" # === # 検索フォルダのファイルを再帰的に検索し、該当行および、その前後の行をメモ帳に保存し開きます。 Get-ChildItem . -Include "${fileName}.${extension}" -Recurse -Force | ` Select-String -Encoding default -context $startRow,$endRow -Pattern $searchStr | ` Out-File -FilePath $outFile -Encoding default notepad $outFile # コンソール画面をクリア。 cls |
できました。
検索テスト用フォルダとファイルの作成
保存ができたら、テスト用に検索を行うフォルダとファイルも必要だから下記と同じように作成してね。
- Cドライブに「test_grep」フォルダを作成。
- Cドライブに「test_results」フォルダを作成。
- 「test_grep」フォルダに「test_grep2」フォルダを作成。
- 「test_grep」フォルダに「grep1.txt」ファイルを作成。
- 「test_grep」フォルダに「grep2.txt」ファイルを作成。
- 「test_grep2」フォルダに「grep3.txt」ファイルを作成。
grep1〜3.txtには、すべて同じ内容で問題ないので、下記を入力してね。
1 2 3 4 5 6 7 8 9 10 |
1行目になります。 2行目になります。 3行目になります。 4行目になります。 5行目になります。 7行目になります。 8行目になります。 9行目になります。 10行目になります。 |
フォルダの作成と、ファイルの作成が終わりました。
検索スクリプトの実行
じゃあとりあえず、PowerShell_ISEの画面で「F5キー」を押して、プログラムを実行してみようか。(前回は「F8キー」での実行だったけど、違いは、1行のみ実行するか全ての行を実行するかになるよ。)
勝手にメモ帳がたちあがりました!
無事成功できてよかった。これがファイル内の文字検索を行って、ヒットした検索結果になるよ。
スクリプトの説明
…中身を見ても、よくわかりません。
だよね(笑)PowerShellのコードと合わせて順番に説明していくよ。
お願いします。
もう一度、PowerShell_ISEのコードを表示するね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# === # 検索フォルダの場所。 cd c:\test_grep # ファイル名(あいまい検索は*を使用) $fileName = "grep*" # 拡張子(あいまい検索は*を使用) $extension = "txt" # 検索結果該当行から何行前まで表示するか。 $startRow = 1 # 検索結果該当行から何行後まで表示するか。 $endRow = 2 # 検索文字 $searchStr = "5行" # 出力結果を保存する場所。 $outFile = "c:\test_results\grep_results.txt" # === # 検索フォルダのファイルを再帰的に検索し、該当行および、その前後の行をメモ帳に保存し開きます。 Get-ChildItem . -Include "${fileName}.${extension}" -Recurse -Force | ` Select-String -Encoding default -context $startRow,$endRow -Pattern $searchStr | ` Out-File -FilePath $outFile -Encoding default notepad $outFile # コンソール画面をクリア。 cls |
3行目の「cd c:¥test_grep」で検索フォルダを指定しているよ。今回は、test_grepフォルダあるファイルと、test_grep2フォルダにあるファイルの中身を検索したいから、親フォルダである、test_grepフォルダを指定しているよ。
ふむふむ。調べたいファイルがある親フォルダを、指定すれば良いわけですね。
うん。次に、5行目の「$fileName=”grep*”」だけど、ここでは、検索したいファイル名を指定しているんだ。今回は、「grep1.txt」「grep2.txt」「grep3.txt」の3つのファイル名から検索を行いたいから、検索文字に「grep*」を指定しているよ。
最後の「*」マークはどういう意味ですか?
これはワイルドカードといって、1つ前の文字以降をあいまい検索するときに利用できるよ。今回の場合、grepという文字までは完全に一致していないといけないけど、それ以降はなんでもいいよ。という意味になるよ。
なるほど。
続いて9行目の「$extension=“txt”」は、検索を行いたいファイルの拡張子を指定しているよ。今回はtxtファイルを作成したからtxtを指定しているけど、全ての拡張子を検索したい場合は、ここで「*」のみを指定するとできるよ。
それは便利ですね!
順番が前後しちゃうけど、先に18行目の「$searchStr=“5行”」から説明するね。ここで検索したい文字を入力しているんだ。この場合、「5行」という文字が含まれているファイルを検索しているよ。
わかりました。
続いて12行目の「$startRow=1」と15行目の「$endRow=2」だけど、「$searchStr=“5行”」で指定した文字がファイルの中にあった場合、その前後の行を何行分返すかを指定しているよ。なので、今回の検索結果で「5行」という文字が含まれる行の前の1行(4行目になります)という文字と「5行」という文字が含まれる行の次の2行(空白行と7行目になります)という文字が表示されているよ。
なるほど。そういった意味があったんですね!
それらを踏まえた上でもう一度メモ帳を見てみるよ。
どう?わかりそう?
えっと、左端に表示されている「>」はどういう意味ですか?
これは、検索してヒットした文字が含まれる行という意味になるよ。
そういう意味なんですね。先程の説明で、該当した行の1行上と2行下も表示する設定にしていたので、「>」の行の上に1行分、下に2行分表示されているという訳ですね。
そうそう。大正解。
あと検索フォルダの中にさらにフォルダがある場合、ファイルパスも表示してくれるのは便利ですね!
うん。それもこのスクリプトのいいところなんだ。
ちなみに、スクリプトの21行目の「$outFile=“c:\test_results\grep_results.txt”」と25行目から始まる長い文字の羅列はどういった意味になるんですか?
「$outFile=“c:\test_results\grep_results.txt”」は結果をテキストとして書き出す場所になるよ。ここに書き出したいから、最初にCドライブの直下にtest_resultsフォルダを作ってもらったんだ。25行目からは、それまでに設定したファイル名や拡張子、検索ワードなどを元に文字検索を行うといった意味になるよ。全部説明するとかなり長くなっちゃうから、興味があったら、「PowerShell Select-String」などで検索して調べてみてね!
わかりました。
まとめ
今回はPowerShellを利用して、Windowsの標準機能だけで実装できる文字検索方法についてご紹介しました。私は医療機関に務めているのですが、保険診療の明細データ(いわゆるレセプトデータ)等から特定の医療行為のデータを抽出したりとか、膨大なCSVファイルから特定の文字だけ抜き出したい場合などに利用しています。
何かのお役に立てれば、幸いです。
コメント