awk を使用して行 (レコード) を分割する方法は?

awk を使用して行 (レコード) を分割する方法は?

ファイル:

data
A B
C D
data
E F
G H
data
I J
K L
M N

望ましい結果:

I J
K L
M N

「データ」で分割するにはどうすればいいでしょうか? awk の使い方を Google で検索しましたが、関連する awk のほとんどは列を分割するものでした。

答え1

dataレコード区切りとして使用し、最後のレコードを印刷するには:

$ awk -v RS=data 'END{print}' File

I J
K L
M N

これには、 の複数文字値をサポートする GNU awk (gawk) や mawk などの awk が必要ですRS

答え2

$ awk '/^data/ { lines = ""; next } { lines = (lines == "" ? $0 : lines ORS $0) } END { print lines }' file
I J
K L
M N

これはawk、文字列 で始まる最後の行以降の入力内容を取得するためにを使用しますdata。これは、そのような行の後の各行セクションを変数に保存することによって行われますlines。 で始まる行に遭遇するたびにdata、この変数は空になります。入力の最後に到達すると、変数の値が印刷されます。


使用方法sed:

$ sed -n 'H;${ x; s/.*\ndata\n//p; }' file
I J
K L
M N

すべての行をホールド スペースに追加します。最後の行に到達すると、ホールド スペースはパターン スペースにスワップされ、文字列 (両側に改行がある) までのすべてがdata削除されてから、残りのビットが印刷されます。


使用方法ed:

$ printf "?^data?ka\n1,'ad\n,p\nQ\n" | ed -s file
I J
K L
M N

または、

ed -s file <<END_ED
?^data?ka
1,'ad
,p
Q
END_ED

dataここでは、まず、行の先頭で文字列の最後の出現を逆方向に検索し、その行にラベルを付けます (ラベル と呼びますa)。次に、バッファの先頭からラベルの付いた行までを削除します。 は、,pバッファの内容全体を単純に出力します。

GNU 以外の場合ed、final Q(保存せずに終了する) はおそらく必要ありません。

答え3

改行ではなく「データ」でレコードを分割するには、RS (レコード区切り) 変数を設定します。

4 番目のレコードのみに関心があります (最初のレコードは最初の「データ」の前にあるため、空です)。そのため、NR が 4 の場合にのみ印刷します。

cat file | awk 'BEGIN {RS="data\n"}; NR==4 {print}'

答え4

以下の方法で実行し、正常に動作しました。コマンド:

tac file.txt|sed -n '1,/data/p'| tac| sed -n '2,$p'

出力

 I J
 K L
 M N

関連情報