複数行を対象にパターン検索したい時はpcregrep -Mが便利!

知人からの依頼で、大量の HTML ファイルから、特定のパターンが含まれている場合にその行を取り出すことをしてほしいと頼まれました。

パターン検索をする範囲が単一行であれば、grep をかければ済みますが、今回のケースはそうではありませんでした。

次のような感じの「複数行にまたがるパターン」を検索して、抽出してほしいというのです。

<th>行ったことのある国</th>
<td>
    フランス<br>
    イギリス<br>
    中国
</td>

つまりは、テーブルの見出し(th)内に「行ったことのある国」という行がある。

そして、テーブルのデータ(td)内に国名がある。国名の数はファイルごとに増えたり減ったりする。

まとめると、「<th>行ったことのある国</th>」で始まり、「</td>」で終わるパターンを検索すればOKです。

でも、複数行にまたがるパターンを検索する方法ってどうやるんだろう?と思って調べたところ、ありました。pcregrep -M です。以下でご説明します。

スポンサーリンク

やり方

次のようなコマンドとなります。

pcregrep -M '<th>行ったことのある国</th>[\s\S]*?</td>' *

[\s\S]*? というのは「改行文字も含めたすべての文字1文字の繰り返しで、もっとも短いもの」という意味になるようです。

最後の「*」の部分はファイル名です。(ここではファイルがたくさんある前提なので「*」としています。)

実際の実行結果としては次のような感じです。

# ls
test
# cat test
<table>
        <th>行ったことのある国</th>
        <td>
                フランス<br>
                イギリス<br>
                中国
        </td>
</table>
# pcregrep -M '<th>行ったことのある国</th>[\s\S]*?</td>' *
        <th>行ったことのある国</th>
        <td>
                フランス<br>
                イギリス<br>
                中国
        </td>

インストールが必要な場合

実は私の環境には pcre コマンドがありませんでしたので、最初はうまくいきませんでした。次のようにしてインストールしました。

# yum install pcre-tools

謝辞

次のページを参考にしました。ありがとうございます。

pcregrepで複数行の文字列をマッチさせる - Qiita
複数行にまたがる文字列をgrepで検索したいときには、 perlの正規表現が使えるpcregrepが便利です。 #インストール CentOS6には標準でインストールされていますが、 CentOS7やAmazonLinuxの場合は、 ...
grepで複数行を対象にサーチ - minus9d's diary
grep -Pオプションを使って複数行を検索する方法 grepは単一行のみしか検索できないのかと思っていたが、オプションを使うとできることが分かった。 例として、検索対象のテキストtest.txtに以下のように書かれているとする。 aaabbbccc dddeeefff ggghhhiiiこのテキストから、「bbbで始...