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
どうして?
正規表現で_\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
_
一致する必要があるのが本当に行の先頭のスペースだけである場合は、_\s
_を1つ以上のスペース_" +"
_に変更することをお勧めします。
正規表現を'banana.*\n( +.*\n)*'
に変更すると、より正確だと思う方法で(正規表現と逆関数の両方で)一致します。タブも許可されている場合は、_[ \t]+
_を使用することもできます。
このようなタスクは、awk
imoに適しています
$ 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
は条件を否定します