grep -Pオプションを使って複数行を検索する方法
grepは単一行のみしか検索できないのかと思っていたが、オプションを使うとできることが分かった。
例として、検索対象のテキストtest.txtに以下のように書かれているとする。
aaabbbccc dddeeefff ggghhhiii
このテキストから、「bbbで始まってdddで終わる文字列」を検索するのは以下のようにすればできる。
$ grep -P 'bbb[\s\S]*?ddd' test.txt
記号の意味を簡単に解説。
このコマンドで表示される結果は以下。
aaabbbccc dddeeefff
これだと、求める文字列を含む行ごとすべて表示されてしまっている。もし厳密にマッチする部分のみが欲しいのなら、grepに-oオプション(only-matchingの意味)をさらに追加すればよい。
$ grep -oP 'bbb[\s\S]*?ddd' test.txt
こうすると以下の結果が得られる。
bbbccc ddd
pcregrepを使って複数行を検索する方法
別解として、pcregrepというコマンドを使う方法もある。このコマンドを使うにはPCREパッケージを入れる必要があるかもしれない。手持ちのMacでは
$ sudo port install pcre
することでpcregrepの準備ができた。
pcregrepでは-Mオプション(multilineの意味)を使うことで、複数行を対象に検索できるようになる。
$ pcregrep -M 'bbb[\s\S]*?ddd' test.txt
結果は
aaabbbccc dddeeefff
pcregrepでもgrepと同様、-oオプションを加える事で厳密にマッチする部分のみを表示することができる。
参考
- http://stackoverflow.com/questions/3717772/regex-grep-for-multi-line-search-needed
- grepの-Pオプションの存在をこれで知った。ただこの例を真似すると、”The -P and -z options cannot be combined”といって怒られる。
- http://stackoverflow.com/questions/2686147/how-to-find-patterns-across-multiple-lines-using-grep
- pcregrepの存在をこれで知った。