この質問に対する答え:
一致するパターン間の複数の行シーケンスは気にしません。例えば、sed -n '/startpattern_here/,/endpattern_here/p'
これらのパターンが現れる間に一連の複数行が印刷される。
しかし、単に印刷したいとしましょう。最後ファイルにこれらの順序があります。 sedを使用してこれを実行できますか?そうでなければ、おそらく奇妙に思えますか?他にはありませんか?
メモ:
- これらのシーケンスは重複しないと仮定することができる。
- 開始および終了パターンラインしなければならない出力に含まれます。
- 複雑さの低いパターンを想定する答えも有効です(最適ではありませんが)。
答え1
完全正規表現テストが必要な場合は、次のように動作します。
awk '/startpattern_here/ {buf="";f=1}
f{buf=buf $0 "\n"}
/endpattern_here/ {f=0; lastcomplete=buf}
END{printf("%s",lastcomplete)}' file.txt
これにより、完全な開始 - 停止パターンのみが印刷されます。
テストケース:
irrelevant
irrelevant
irrelevant
startpattern_here
relevant_but_dont_show_1
relevant_but_dont_show_1
relevant_but_dont_show_1
endpattern_here
irrelevant
irrelevant
startpattern_here
relevant_but_dont_show_2
relevant_but_dont_show_2
relevant_but_dont_show_2
endpattern_here
irrelevant
irrelevant
startpattern_here
relevant_and_show
relevant_and_show
relevant_and_show
endpattern_here
irrelevant
startpattern_here
incomplete_dont_show
結果:
startpattern_here
relevant_and_show
relevant_and_show
relevant_and_show
endpattern_here
ノート開始モードと終了モードの出力を抑制するには、sumsルールを変更するだけです/startpattern_here/ { ... }
。/endpattern_here/ { ... }
つまり、「終了モード」ルールを最初に配置し、END
次に「開始モード」ルールを配置するだけです。
答え2
tacとawkの組み合わせ
tac file \
| awk '
!p && /endpattern_here/ {p = 1}
p {print}
p && /startpattern_here/ {exit}
' \
| tac
答え3
そして前任者(POSIXエディタ)とてもシンプルです。
printf '%s\n' 1 '?END?' '?START?,.p' | ex -s file
1
ファイルの最初の行に移動します。これはファイルの最後の行である場合にEND
必要です。?END?
ファイルの末尾から後ろに検索して、END
ファイルに最後に表示される項目を見つけます。?START?,.p
START
前のアドレスから現在のアドレスまですべて印刷します。
printf
以下は、多様性のためにhere-docsを代わりに使用する例です。
$ cat file
zdk
START
b12
END
kdn
START
000
111
END
START
ddd
$ ex -s file <<EOF
> 1
> ?END?
> ?START?,.p
> EOF
START
000
111
END
答え4
1つの方法は、単に各グループを保存し、次のグループで上書きして最後に達したときに保持したグループを印刷することです。
awk '{
if(/startpattern_here/){
a=1;
lines=$0;
next
}
if(a){
lines=lines"\n"$0
}
if(/end_pattern/){
a=0
}
}
END{
print lines
}' file
たとえば、次のテストファイルを使用します。
startpattern_here
line 1
line 2
line 3
end_pattern
startpattern_here
line 1b
line 2b
line 3b
end_pattern
startpattern_here
line 1c
line 2c
line 3c
end_pattern
私は得る:
$ awk '{ if(/startpattern_here/){a=1; lines=$0; next} if(a){lines=lines"\n"$0} if(/end_pattern/){a=0}} END{print lines}' file
startpattern_here
line 1c
line 2c
line 3c
end_pattern