2つのパターン間の出力を印刷したいです。最初のパターンはファイル内で2番目に一致する必要があります。
はい -
test.txt
start one
text_1
end
start two
text_2
end
start three
text_3
end
ここで、最初のモードはstart
で、2番目のモードはですend
。パターンはstart
ファイル内の2番目のパターン一致でなければなりません。その後、出力は次のようになります
start two
text_2
end
答え1
以下を使用してn番目のレコードにawk
簡単に拡張できます。
awk '/start/ && ++n == 2, /end/' < file
start
2番目の発生から最初の発生まで行を印刷しますend
。
2番目のstart
レコードを印刷します(、end
がある場合は順序が異なります)。start
start
end
awk '
/start/, /end/ {
if (!seen) {seen = 1; n++}
if (n == 2) print
if (/end/) seen = 0
}' < file
または:
awk '
!inside && /start/ {inside = 1; n++}
!inside {next}
n == 2
/end/ {inside = 0}' < file
答え2
そしてsed
sed -n '/start/,/end/n;/start/,/end/{p;/end/q}' file
説明する:
-n
出力抑制- 最初に
/start/,/end/n
最初から始まるまでブロックを抽出し、何もしません(passn
)。 - 次に、最初から最後まで2番目のブロック印刷を実行し
/start/,/end/
、最後に到達するとすぐに終了します。p;/end/q
答え3
この特別な場合 - 入力が/start/,/end/
ブロックのみで構成されている場合は、単に次のことができます。
sed '1,/end/d;//q' infile
このブロック間に異なる行がある場合(一致なしend
)
sed '1,/end/d;/start/,/end/!d;/end/q' infile
より一般的な場合、抽出するチャンクがn
1つの場合は、次のように実行できます。
n=5
awk -vc=$n '/start/{i++};{if (i==c){print;if (/end/){exit}}}' infile
答え4
sed -ne '
/^start/,/^end/!d; # skip non-interesting block
/^start/H; # increment hold counter
G;/\n.*\n.*\n/!d; # check if 2nd block reached?
P;/^end/q; # we"re in 2nd block so print & quit on /end/
' yourfile
perl -l -0777ne 'print+(/^start.*?\nend[^\n]*$/msg)[1]' yourfile