以下にリストされているファイルがあると思います。正規表現パターンの各インスタンスですべてのWord A
行を選択する必要があります。今後正規表現パターンWord D
。
Word A
Word B
Word C
Word D
Word E
Word F
Word G
Word A
Word H
Word I
Word D
Word J
Word A
Word K
Word D
Word L
Word M
Word A
Word D
A
との間の行数は異なりますD
。時にはD
次の行があります。これは私が必要とする出力です。
Word A
Word B
Word C
Word A
Word H
Word I
Word A
Word K
Word A
これはawk、Perl、Python、またはsedを使用して実行できます。ファイルが存在するRHEL6サーバーにインストールされていても問題はありません。
答え1
AWKを使用:
awk '/Word A/ { m = 1 } /Word D/ { m = 0 } m'
答え2
ここにawk
解決策があります
awk \
-vstart='Word A' \
-vend='Word D' \
'{
if ($0==end ) {flag=0;next};
if ($0==start) {flag=1};
if (flag==1) {print $0};
}'
正規表現処理にはわずかな変更しか必要ありません。
awk \
-vstart='Word[ ]A' \
-vend='Word[ ]D' \
'{
if ($0 ~ end ) {flag=0;next};
if ($0 ~ start) {flag=1};
if (flag==1) {print $0};
}'
答え3
使用幸せ(以前のPerl_6)
~$ raku -ne '.put if / Word \h A / fff^ / Word \h D /;' file
RakuはPerlファミリーのプログラミング言語です。強力な正規表現エンジンを備えた「演算子が豊富な」言語です。上記では、Rakuのsedに似た「トリガー」演算子で-ne
自動印刷されない限り、1行ずつフラグが使用されました。fff
Rakuには、さらにを含むfff
sedに似た中位演算子のさまざまな「特性」が含まれています。各正規表現が認識されると、キャレットは認識された行を出力から削除する必要があることを示します。fff^
^fff
^fff^
^
入力例:
Word A
Word B
Word C
Word D
Word E
Word F
Word G
Word A
Word H
Word I
Word D
Word J
Word A
Word K
Word D
Word L
Word M
Word A
Word D
出力例:
Word A
Word B
Word C
Word A
Word H
Word I
Word A
Word K
Word A
上記のコードはOPのテストケースを解決します。しかし、Regexesが実際に同じ行にある場合はどうなりますか/start/
?/stop/
この問題の場合は、Rakuのawk様演算ff
子を試してみてください。
~$ echo 'AB\nCD\nEF' | raku -ne 'say $_ if /A/ ff /B/;'
AB
~$ echo 'AB\nCD\nEF' | raku -ne 'say $_ if /A/ ff /C/;'
AB
CD
Rakuのsed様演算fff
子と比較してみてください。
~$ echo 'AB\nCD\nEF' | raku -ne 'say $_ if /A/ fff /B/;'
AB
CD
EF
~$ echo 'AB\nCD\nEF' | raku -ne 'say $_ if /A/ fff /C/;'
AB
CD
https://docs.raku.org/routine/fff
https://docs.raku.org/routine/ff
https://raku.org
答え4
TXR リースawk
マクロはこれを直接サポートします。rng
(範囲)演算子には、さまざまな方法で範囲の始まりまたは終わりからレコードを除外する9つのバリエーションがあります。
$ txr -e '(awk ((rng- #/Word A/ #/Word D/)))' data
Word A
Word B
Word C
Word A
Word H
Word I
Word A
Word K
Word A
また、Awk の範囲演算子とは異なり、他の演算子と一緒に使用されます。たとえば、foo
範囲bar
内のレコードを印刷したいとします。そしてstart
範囲内では、end
データ内の範囲がどのように重なっているかに関係なく、次のことが行われます。
(awk ((and (rng #/foo/ #/bar/)
(rng #/start/ #/end/))))