最初のパターンが2番目に表示される場合にのみ、2つのパターンの間に印刷

最初のパターンが2番目に表示される場合にのみ、2つのパターンの間に印刷

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

start2番目の発生から最初の発生まで行を印刷しますend

2番目のstartレコードを印刷します(、endがある場合は順序が異なります)。startstartend

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最初から始まるまでブロックを抽出し、何もしません(pass n)。
  • 次に、最初から最後まで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

より一般的な場合、抽出するチャンクがn1つの場合は、次のように実行できます。

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

関連情報