
次の形式のデータファイルがあります。
Header:H1
Sub-header:H1S1
Record:R1
Record:R2
Sub-header:H1S2
Record:R5
Record:R6
Sub-header:H1S3
Record:R9
Record:R10
Header:H2
Sub-header:H2S1
Record:R15
Record:R16
Header:H3
Sub-header:H3S1
Record:R25
Record:R26
Sub-header:H3S2
Record:R30
Record:R31
ファイルが次の形式を持つようにAWKを使用してこのファイルを処理したいと思います。
H1, H1S1, R1
H1, H1S1, R2
H1, H1S2, R5
H1, H1S2, R6
H1, H1S3, R9
H1, H1S3, R10
H2, H2S1, R15
H2, H2S1, R16
H3, H3S1, R25
H3, H3S1, R26
H3, H3S2, R30
H3, H3S2, R31
どうすればいいですか?
答え1
タイトルとサブタイトルを表示するときは覚えておき、Record:行を表示するとき(記録データとともに)印刷する必要があります。
$ awk -F: -v OFS=", " '/^Header:/ { header = $2; next };
/^Sub-header:/ { subheader = $2; next };
/^Record:/ { print header, subheader, $2 }' input.txt
H1, H1S1, R1
H1, H1S1, R2
H1, H1S2, R5
H1, H1S2, R6
H1, H1S3, R9
H1, H1S3, R10
H2, H2S1, R15
H2, H2S1, R16
H3, H3S1, R25
H3, H3S1, R26
H3, H3S2, R30
H3, H3S2, R31
このnext
声明は小さな最適化です。必要$ 2を抽出すると、次の入力行に移動してスクリプトの上部から再処理を開始します。
このようなスクリプトでは、パフォーマンスにほとんど影響しません。それほど多くの影響はありません。多数のパターンを一致させる必要があるか、計算を実行する必要があるより複雑なスクリプトの場合、これは大きな影響を与える可能性があります。
答え2
:
入力ファイルにスペースが含まれていないと仮定すると、次のawk
プログラムがこれを行います。
awk 'BEGIN{FS=":";OFS=","} $1=="Header"{h=$2} $1=="Sub-header"{s=$2} $1=="Record" {print h,s,$2}' input.txt
まず、:
フィールド区切り文字を入力に設定し、フィールド,
区切り文字を出力に設定します。
次に、最初の入力フィールドの名前がandに指定されるたびに、最新のヘッダーとサブヘッダーを読み取り、それぞれh
変数に保存します。行が見つかると、フィールド値とそれぞれに格納された値が印刷されます。s
Header
Sub-header
Record
h
s
Sub-header
ここでは、最初の項目の前に常に付いていると仮定しますRecord
。空の字幕を許可するには、最初のルールブロックを次から変更してください。
$1=="Header"{h=$2}
到着
$1=="Header"{h=$2;s=""}
答え3
入力にタグ値のペアがある場合は、まずマップを保存する配列を作成することをお勧めします(f[]
下)。その後、値(名前)でアドレスを指定して、値タグにアクセス/印刷/比較/変更/すべての値を指定できます。 :
$ cat tst.awk
BEGIN { FS=":"; OFS=", " }
{ f[$1] = $2 }
/^Record/ { print f["Header"], f["Sub-header"], $2 }
$ awk -f tst.awk file
H1, H1S1, R1
H1, H1S1, R2
H1, H1S2, R5
H1, H1S2, R6
H1, H1S3, R9
H1, H1S3, R10
H2, H2S1, R15
H2, H2S1, R16
H3, H3S1, R25
H3, H3S1, R26
H3, H3S2, R30
H3, H3S2, R31