web-dev-qa-db-ja.com

ファイル内の複数行パターンを検索するにはどうすればよいですか?

特定の文字列パターンを含むすべてのファイルを見つける必要がありました。頭に浮かぶ最初の解決策は、findxargs grepでパイプ処理することです:

find . -iname '*.py' | xargs grep -e 'YOUR_PATTERN'

しかし、複数の行にまたがるパターンを見つける必要がある場合、Vanilla grepは複数行のパターンを見つけることができないため、立ち往生しています。

111
Oli

そこで私は発見した pcregrepPerl互換の正規表現GREP

たとえば、「_ name」変数の直後に「_ description」変数が続くファイルを見つける必要があります。

find . -iname '*.py' | xargs pcregrep -M '_name.*\n.*_description'

ヒント:パターンに改行文字を含める必要があります。プラットフォームによっては、 '\ n'、\ r '、'\r\n '、...

93
Oli

awk に行ってみませんか?

awk '/Start pattern/,/End pattern/' filename
87
Amit

GNU grep を使用した例を次に示します。

grep -Pzo '_name.*\n.*_description'

-z/--null-data入力および出力データを行のシーケンスとして扱います。

here も参照してください

70
ayaz

grep -Pもlibpcreを使用していますが、muchより広くインストールされています。 HTMLドキュメントの完全なtitleセクションを見つけるには、たとえそれが複数行にわたる場合でも、これを使用できます:

grep -P '(?s)<title>.*</title>' example.html

PCREプロジェクト はPerl標準に実装されているため、参照用にPerlのドキュメントを使用してください。

20
bukzor

より便利な例を次に示します。

pcregrep -Mi "<title>(.*\n){0,5}</title>" afile.html

5行に及ぶ場合でも、htmlファイル内のタイトルタグを検索します。

無制限の行の例を次に示します。

pcregrep -Mi "(?s)<title>.*</title>" example.html 
15
Oli

シルバーサーチャー の場合:

ag 'abc.*(\n|.)*efg'

シルバーサーチャーの速度の最適化がここで光る可能性があります。

7
Shwaydogg

ここでgrepの代替 ​​sift を使用できます(免責事項:私は著者です)。

複数行のマッチングをサポートし、すぐに検索を特定のファイルタイプに制限します。

sift -m --files '* .py' 'YOUR_PATTERN'

(指定された複数行正規表現パターンのすべての* .pyファイルを検索します)

すべての主要なオペレーティングシステムで使用できます。 サンプルページ を見て、XMLファイルから複数行の値を抽出するためにどのように使用できるかを確認してください。

4
svent

この答えは役に立つかもしれません:

複数行の検索には正規表現(grep)が必要

再帰的に検索するには、フラグ-R(再帰)および--include(GLOBパターン)を使用できます。見る:

grep --exclude /-特定のファイルをgrepしないように構文を含める を使用

3
albfan
Perl -ne 'print if (/begin pattern/../end pattern/)' filename
2
pbal

@Marcin:awkの貪欲でない例:

awk '{if ($0 ~ /Start pattern/) {triggered=1;}if (triggered) {print; if ($0 ~ /End pattern/) { exit;}}}' filename
1
Martin

ex/viエディターおよび globstarオプションawkおよびsedと同様の構文)を使用します。

ex +"/string1/,/string3/p" -R -scq! file.txt

ここで、aaaは開始点であり、bbbは終了テキストです。

再帰的に検索するには、次を試してください:

ex +"/aaa/,/bbb/p" -scq! **/*.py

注:**構文を有効にするには、shopt -s globstar(Bash 4またはzsh)を実行します。

1
kenorb