バナナ行で始まるすべての行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
できることを意味します。私は-v
pcregrepの実装に慣れていないので、なぜその逆ではないのかわかりませんが、その理由は明らかです。
ファイルを次のように変更する場合:
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
条件を否定しながら、条件に一致する行を印刷します。