数学、ときどき統計、ところによりIT

理論と実践の狭間で漂流する数学趣味人の記録

Windows 版 grep

grep は言わずと知れた文字列検索コマンドです。
UNIX 系 OS では、OS をインストールした直後から標準で使えますが Windows では使えません*1

似た機能を持つコマンドに find や findstr があるのですが、機能が貧弱にも関わらずパラメータの指定にクセがあり、正直言って使う気になれません。

かといって Cygwin は明らかにオーバースペック。

"Windows grep" でググってみても find や findstr コマンドの結果が山の様に出てくる始末…。
「無いなら自分で作るしかないか…」
簡易版の grep を作るべくコーディングを始めましたが
「いやいや待て待て、こんな基本的なコマンド、無いと困る!と思っている奴は他にも絶対いる!」*2
と思い直しググり続けた結果、見つけました!

BusyBox

標準的な UNIX コマンドをオールインワンにしたプログラムで、実行ファイルサイズが小さくなるように設計されていることから、特に組み込み系で良く使われ「組み込み Linux の十徳ナイフ」*3とも呼ばれています。

WindowsBusyBoxの入手方法ですが、まずは配布元へ行きます。どこからダウンロードするのか、一見すると分かりにくいものの

From time to time binary builds and source tarballs will be made available. The latest version is always busybox.exe.

とあり、実行ファイルへの直リンクがあるので、それをクリックするとダウンロードが開始されます。

使い方ですが、例えば input.txt から検索文字列 "abc" を含む行を抽出して output.txt に出力する場合、

busybox grep "abc" input.txt > output.txt

となります*4
grep で使えるオプションですが、コマンドラインで引数を何も付けずに "busybox grep" を実行すればヘルプが表示されます。

さて、テストを初めて直ぐに気が付いたのは文字コードの問題でした。 Shift-JIS のファイルは問題無く処理できるのに UTF-8 のファイルは処理できない。ヘルプを見ても文字コードを指定するコマンド引数は存在せず。nkf を使って予め Shift-JISに変換してから検索をする方法はあるものの、UTF-8 から Shift-JIS への変換は、対応する文字が無い場合、文字化けするので出来るだけ使いたくはない…。
結論を言うと、検索パターンをファイルから読み込ませる -f オプションを使うことで上手く処理することができました。
まずは検索パターンをテキストファイルに保存します。これを pattern.txt とします。このとき pattern.txt の文字コードは input.txt の文字コードと同じもの*5にしておきます。そして次のコマンドを実行します。

busybox grep -f pattern.txt input.txt > output.txt

検索結果を収めたファイル output.txt の文字コードは input.txt と同じものになっています。
1つのパターンのみを検索したい場合、いちいち検索パターンをファイルに保存しなければならない点はデメリットではありますが、実際の運用では数十以上のパターンを検索する予定の為、この点が問題になることはありません。

Grep for Windows

こうして目的は果たせたのですが、後から "Windows grep" でググった結果の中に "Grep for Windows" というツールに関する結果が埋もれているのを発見*6。これは GNU のツールを Windows に移植するプロジェクトの成果物の様で、折角なのでこれも試してみることにしました。

SourceForge から setup プログラムをダウンロードし、適当なフォルダにインストールします。
busybox と同じテストをしてみた結果、なんと検索パターンファイルを使ったやり方でも UTF-8 のファイルを処理できないことが判明!
結果論ですが、はじめに busyboxgrep を試しておいて良かったということでしょうか。

*1:Windows10 では Windows Subsystem for Linux という機能によって Linux で使われているコマンドが使えるらしいのですが、残念ながら自分の使っているマシンは Windows10 ではありません。

*2:車輪の再発明」という警句は常に頭のどこかに置いておかなければいけない言葉です。

*3:https://ja.wikipedia.org/wiki/BusyBox

*4:検索対象となるファイルと同じフォルダに busybox.exe を置くか、busybox.exe のあるフォルダにパスを通してある場合の記法です。

*5:input.txt が UTF-8(BOMあり)の場合、pattern.txt は UTF-8(BOMなし)にして下さい。

*6:何故、これが1位に表示されないのかが不思議です。