次の内容を含むファイルがあります。
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行があります)。
この目標をどのように達成できますか?
答え1
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
もちろん、これらすべての条件は、1行が完全に含まれていることを確認し、aaa
他cdn
のものが含まれていないことを確認するなど、より限定的な正規表現に拡張できます。
答え2
これは次の方法で行うことができます。sed
sed -n '
/^aaa$/,/^cdn$/w output1
/^zdk$/,/^dke$/w output2
' file
答え3
これはgrep
コマンドです:
grep -o "aaa.*cdn" <(paste -sd_ file) | tr '_' '\n'
複数行の一致を達成できますが(-OS Xなどのすべてのプラットフォームではサポートされていません)、grep
perl-regexpを使用する必要があります。したがって、回避策として新しい行を文字に置き換えてから再度変更します。grep
-P
_
grep
またはあなたは使用することができますpcregrep
マルチラインモード(-M
)をサポートします。
または以下を使用してくださいex
。
ex +"/aaa/,/cdn/p" -scq! file