次の内容のファイルがあります。
zdk
aaa
b12
cdn
dke
kdn
入力1:aaa
およびcdn
出力1:
aaa
b12
cdn
入力2:zdk
およびdke
出力2:
zdk
aaa
b12
cdn
dke
以下のコマンドを使用して達成できます:
grep -a aaa -A2 file # Output 1
grep -a aaa -A4 file # Output 2
しかし、ファイルでは、終了文字列パターンの正確な発生(位置)が何であるかわかりません(ファイルには20000行があります)
どうすればこれを達成できますか?
grep
はここでは役に立ちません。これは、範囲式を使用したsed
でよりよく達成される仕事です。
$ sed -n '/aaa/,/cdn/p' file
aaa
b12
cdn
$ sed -n '/zdk/,/dke/p' file
zdk
aaa
b12
cdn
dke
sed -n
は、自動印刷を抑制し、明示的に要求された場合にのみ行が印刷されるようにします。そして、これは/aaa/,/cdn/
の範囲が発生したときに発生します。
これらの範囲式はawk
でも使用できます。
awk '/zdk/,/dke/' file
もちろん、これらすべての条件をsed -n '/^aaa$/,/^cdn$/p' file
のようなより厳密な正規表現に拡張して、行がaaa
とcdn
だけで構成されていることを確認できます。
sed
で実行できます
sed -n '
/^aaa$/,/^cdn$/w output1
/^zdk$/,/^dke$/w output2
' file
これがgrep
コマンドです:
grep -o "aaa.*cdn" <(paste -sd_ file) | tr '_' '\n'
grep
で複数行の一致を実現できますが、grep
(-P
-OS Xなどのすべてのプラットフォームでサポートされているわけではありません)にはPerl正規表現を使用する必要があります。回避策として、改行を_
文字に置き換え、grep
の後に改行します。
または、 pcregrep
を使用して、複数行のパターン(-M
)をサポートすることもできます。
またはex
を使用:
ex +"/aaa/,/cdn/p" -scq! file