2番目のパターンに固有の2つのパターン間のすべての線を見つけますか?

2番目のパターンに固有の2つのパターン間のすべての線を見つけますか?

以下にリストされているファイルがあると思います。正規表現パターンの各インスタンスですべての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には、さらにを含むfffsedに似た中位演算子のさまざまな「特性」が含まれています。各正規表現が認識されると、キャレットは認識された行を出力から削除する必要があることを示します。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/))))

関連情報