はじめに
ど忘れ防止に、grepを使用してパターンを検索する際によく使うオプションを逆引きでメモしておく。
パターン検索方法の色々
パターンが一致しない行を出力する場合、”-v”オプションを指定する。
grep -v pattern input.txt
大文字小文字を区別しない場合、”-i”オプションを指定する。
grep -i pattern input.txt
複数のパターンで検索する場合、”-e”オプションを指定する。
パターン毎にオプションを付けて指定する。パターンが一つならば”-e”オプションは省略できる。
grep -e pattern1 -e pattern2 input.txt
ただし、-8など”-“から始まるパターンで探したい場合は、”-e”オプションが必要となる。
grep -e -8 input.txt
パターンで拡張正規表現を使いたい場合、”-E”オプションを指定する。
grep -E "0x[0-9A-Fa-f]{2}¥b" input.txt
パターンが見つかった行数も出力する場合、”-n”オプションを指定する。
grep -n pattern input.txt
パターンが見つかった行の前後n行を出力する場合、”-行数”オプションを指定する。
grep -3 pattern input.txt # 前後3行を出力する
ファイルパスだけ出力する場合、”-l”オプションを指定する。
grep -l pattern input.txt
サブディレクトリのファイルも対象とした場合の色々
サブディレクトリも対象とする場合、”-r”オプションを指定する。
grep -r pattern .
除外したいディレクトリがある場合は、”–exclude-dir”オプションにパターンを指定する。
grep -r pattern --exclude-dir=.git .
除外したいディレクトリが複数ある場合は、”–exclude-dir”オプションに波括弧で括ったカンマ区切りのパターンを指定する。
grep -r pattern --exclude-dir={.git,.vagrant} .
対象ファイルをパターンで絞り込む。
grep -r pattern --include=*.rb .
対象ファイルを複数のパターンで絞り込む。
grep -r pattern --include={*.rb,*.yml} .
除外ファイルをパターンで指定する。
grep -r pattern --exclude=*.bak
除外ファイルを複数のパターンで指定する。
grep -r pattern --exclude={*.bak,*.html} .
注意
パターンが一つしかない場合に波括弧で括ると処理されないので注意する。
grep -r pattern --exclude={*.bak} . # エラーにならないけど除外とならない。
grep -r pattern --exclude=*.bak . # {}を取った状態にする
検索ファイルにバイナリファイルが含まれる場合の色々
grepはバージョン2.21以降、テキスト以外のバイトデータを行末記号として扱うように変更されました。その後も、実装に変更がありバイナリファイルを対象とした結果がバージョン間で異なるので注意が必要です。2020年4月時点で、アップストリームの最新バージョン(安定版)は、バージョン3.4です。
http://savannah.gnu.org/projects/grep/
以下の実行結果は、centos7.6上のgrep version2.20で確認した結果です。
grepの検索ファイルにバイナリファイルが含まれる場合、デフォルトの動作としてパターンが一致したか否かだけで、一致箇所などの情報は出力されません。デフォルトの動作を変更するには、”–binary-files”オプションでタイプを指定します。指定できるタイプは3つあり、デフォルト以外のタイプには省略表現が用意されています。
「hello, world! 」を出力するだけの実行ファイルを検証用のバイナリファイルとして例を表します。以下のソースをgccでビルドして、実行ファイルa.outを作成した状態を前提とします。
#include <stdio.h>
int main(void)
{
printf("hello, world!¥n");
return 0;
}
バイナリファイルなら無条件で不一致とするなら、”-I”オプションを指定します。
“–binary-files=without-match”オプションの指定と同じです。バイナリファイル内に一致するテキストがあっても不一致として扱われます。何も出力されませんが、終了コードが1になります。
$ grep -I hello a.out
$ echo $?
1
バイナリファイルでもテキストファイルと同様に扱うなら、”-a”オプションを指定します。
“–binary-files=text”オプションを指定した場合と同じです。一致、不一致だけでなく一致箇所も出力されます。ただし、バイナリデータ部分も出力されるため出力が乱れる場合があります。(ような事がmanページに書いてあります)
$ grep -a hello a.out
デフォルト時の動作は以下のようになります。オプションは不要ですが指定した場合は、”–binary-files=binary”を指定した場合と同じです。
$ grep --binary-files=binary hello a.out
Binary file a.out matches
おまけ
“–binary-files”に未知のタイプを指定するとエラーとなります。
$ grep --binary-files=rabbit hello a.out
grep: unknown binary-files type
バイナリファイル内のテキストを検索する機会は少ないですが、サブフォルダ以下のファイルを纏めてgrepの対象とした場合に、バイナリファイルを除外するために”-I”オプションが利用できます。