web-dev-qa-db-ja.com

それらを含む2つのパターン間の最初の出現を選択する方法

それらを含む2つのパターン間の最初の出現を選択するにはどうすればよいですか。できればsedまたはawkを使用してください。

私が持っています:

text
something P1 something
content1
content2
something P2 something
text
something P1 something
content3
content4
something P2 something
text

P1とP2の間のライン(P1ラインとP2ラインを含む)の最初のオカレンスが欲しい:

something P1 something
content1
content2
something P2 something
27
kofucii
sed '/P1/,/P2/!d;/P2/q'

...deleting !範囲外の場合は、quittingが範囲の終わりに初めて遭遇したときに。 P1の前のP2で失敗することはなく、GNU特定の構文で簡単に記述する必要もありません。

23
mikeserv

awk

awk '/P1/{a=1};a;/P2/{exit}' file
something P1 something
content1
content2
something P2 something
9
iruvar

sed内:

sed -n '/P1/,/P2/p; /P2/q'
  • -nはデフォルトの印刷を抑制し、pコマンドを使用して、一致するアドレス範囲間の行を印刷します。
  • 通常、これは両方のセクションに一致するため、最初のP2が一致したときに(q)を終了します。

P2P1の前にある場合、これは失敗します。このケースを処理するには、次のことを試してください。

sed -n '/P1/,/P2/{p; /P2/q}'
8
muru
awk '/P1/,/P2/{print;f=1} f&&/P2/{exit}' data

前ではなく、印刷直後に終了します。

1
dedowsdi

より簡単なawkソリューション(- iruvarの回答muruの回答 の中間のソートですが、変数を使用していません):

awk '/P1/,/P2/ { print }  /P2/ { exit }'

そして、muruが述べたように、最初のP2が最初のP1の前にある場合、これは何も出力しません。

もちろん、すべてのP1-P2範囲を印刷したい場合:

something P1 something
content1
content2
something P2 something
something P1 something
content3
content4
something P2 something

exitの部分は省略してください:

awk '/P1/,/P2/ { print }'

パターン自体をスキップする場合は、awkバージョンを次に示します。

awk '/P2/ {exit} /P1/ {f=1; next} f' file
1
codeforester

パターン自体をスキップし、一致する最初のブロックのみを単一のGNU sedで表示するには:

sed -nre '/STARTPATTERN/ {:a;n;/ENDPATTERN/{b;};p;ba}' file
0
Santrix