開始パターンと終了パターンの間の行を見つける方法は? [コピー]

開始パターンと終了パターンの間の行を見つける方法は? [コピー]

次の内容を含むファイルがあります。

zdk
aaa
b12
cdn
dke
kdn

入力1:aaacdn

出力1:

aaa
b12
cdn

入力2:zdkdke

出力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行が完全に含まれていることを確認し、aaacdnのものが含まれていないことを確認するなど、より限定的な正規表現に拡張できます。

答え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などのすべてのプラットフォームではサポートされていません)、grepperl-regexpを使用する必要があります。したがって、回避策として新しい行を文字に置き換えてから再度変更します。grep-P_grep

またはあなたは使用することができますpcregrepマルチラインモード(-M)をサポートします。

または以下を使用してくださいex

ex +"/aaa/,/cdn/p" -scq! file

関連情報