pcregrepは、必要なものより1行を食べる複数行の正規表現を除外します。

pcregrepは、必要なものより1行を食べる複数行の正規表現を除外します。

バナナ行で始まるすべての行bananaと、バナナ行の後にスペースで始まるすべての行をフィルタリングしたいと思います。を使用していますpcregrep。次のファイルを検討してくださいfruits.txt

apple
banana starts matching
 this line should match
 this too
 and this
mango
pomelo

pcregrep私が探していたものを見つけてうれしいです。

ars@ars-thinkpad ~/tmp/tmp $ pcregrep -M  'banana.*\n(\s.*\n)*' fruits.txt 
banana starts matching
 this line should match
 this too
 and this

ところがこのセリフを除外しようとするとマンゴーも食べることにpcregrepなって良くありません。

ars@ars-thinkpad ~/tmp/tmp $ pcregrep -M -v 'banana.*\n(\s.*\n)*' fruits.txt 
apple
pomelo

なぜ?

答え1

正規表現で使用することは、式が改行文字を食べることが\sできることを意味します。私は-vpcregrepの実装に慣れていないので、なぜその逆ではないのかわかりませんが、その理由は明らかです。

ファイルを次のように変更する場合:

apple
banana starts matching
 this line should match
 this too
 and this

mango

pomelo

そうでなくても、-v試合は好きなように見えません。

$ pcregrep  -M 'banana.*\n(\s.*\n)*' fruits.txt
banana starts matching
 this line should match
 this too
 and this

mango

pomelo

一致する必要がある行の先頭に実際にスペースが1つしかない場合は、スペース\sを1つ以上に変更します" +"

正規表現を'banana.*\n( +.*\n)*' Itに変更すると、より正確であると考えられる方法(正規と逆)に一致します。[ \t]+タブも許可すると機能します。

答え2

awk私の考えでは、そのような仕事がより適していると思われます

$ awk '!/^ /{f=0} /^banana/{f=1} f' fruits.txt 
banana starts matching
 this line should match
 this too
 and this
$ awk '!/^ /{f=0} /^banana/{f=1} !f' fruits.txt 
apple
mango
pomelo
  • フラグが設定された順序は、次から始まる行!/^ /に対しても条件が満たされるため、検索中の特定の行を簡単に印刷または否定するのに役立ちます。banana
  • !/^ /{f=0}行が空白で始まらない場合は、フラグをクリアします。
  • /^banana/{f=1}行が次から始まる場合のフラグの設定banana
  • f!f条件を否定しながら、条件に一致する行を印刷します。

関連情報