次の内容を含むテキストファイルがあります。
タイトル1 A1
タイトル3 A3
タイトル4 A4
タイトル5 A5
タイトル1 B1
タイトル2 B2
タイトル5 B5
タイトル1 C1
タイトル2 C2
タイトル4 C4
タイトル5 C5
タイトル 1 D1
タイトル 2 D2
タイトル 3 D3
私は次の出力が欲しい:
title1 title2 title3 title4 title5
A1 A3 A4 A5
B1 B2 B5
C1 C2 C4 C5
D1 D2 D3
AWKを使ってコードを書く方法を教えてください。
よろしくお願いします!
答え1
空白(または「:」)だけで区切られるようにデータを変更できる場合は、次のawkプログラムがこれを実行できます。レイアウトを完璧にするために調整する必要があるかもしれません。
BEGIN { i = 1; }
$1 != "" { C[$1] = $1; X[$1,i] = $2 ; next; }
{ i++; }
END {
asort(C);
for ( k in C ) printf " %8s\t", C[k];
printf "\n";
for ( j = 1; j <= i; j++ ) {
for ( k in C ) printf "%8s\t",X[C[k],j];
printf "\n";
}
}
答え2
awk -f transpose_rows_to_cols.awk /tmp/1
title1 title2 title3 title4 title5
A1 A3 A4 A5
B1 B2 B5
C1 C2 C4 C5
D1 D2 D3
PS。端末でフォーマットするだけです。
スクリプト -
#!/usr/bin/awk -f
BEGIN {
printf("title1\ttitle2\ttitle3\ttitle4\ttitle5\n");
a["title1"] = a["title2"]= a["title3"]= a["title4"]= a["title5"] = ""
}
{
if ($0 !~ /^$/) {
if ($0 ~ /:/) {FS=":"; $0=$0} else {FS=" "; $0=$0}
a[$1]=$2
} else {
printf("%s\t%s\t%s\t%s\t%s\n", a["title1"], a["title2"], a["title3"], a["title4"], a["title5"])
a["title1"] = a["title2"]= a["title3"]= a["title4"]= a["title5"] = ""
}
}
END{
printf("%s\t%s\t%s\t%s\t%s\n", a["title1"], a["title2"], a["title3"], a["title4"], a["title5"])
}
答え3
この回答は以下に基づいています。Ralph Rehnquistの回答、しかし
- 列は、ヘッダーごとのアルファベット順ではなく、ユーザーが指定した順序で出力する必要があるとします。
- データ値は複数の単語が許可されます。
Ralphの答えと同様に、タイトルがコロンではなく空白でデータから分離されているとします。
目標1を達成するには、入力が必要な順序ですべてのヘッダー(付随するデータなし)を含むセクションから始める必要があります。
BEGIN { i = 0; j= 0; }
$1 != "" { if (i==0) C[++j] = $1; else { label = $1; $1 = ""; X[label,i] = $0; } next; }
{ i++; }
END {
for ( k in C ) printf " %8s\t", C[k];
printf "\n";
for ( j = 1; j <= i; j++ ) {
for ( k in C ) printf "%8s\t", X[C[k],j];
printf "\n";
}
}
はでi
初期化され0
、そのi==0
ケースは特別に処理されます。ヘッダーだけがキャプチャされ(これが必要な唯一のものなので)、ヘッダーは値ではなくC
増分整数()で索引付けされた配列に格納されます。j
ヘッダ自体の。それ以外の場合はデータをキャプチャします。
$1 = "";
行の最初のフィールドを削除し、他のすべてのフィールドを$0
リンクして再構築します。 (これにより、フィールド間に複数のスペースが失われます。これはいくつかの操作で変更される可能性があります。)データ配列のインデックスとして使用できるように、値を変数に保存します$1
。label
X
たとえば、次の入力は次のようになります。
name
address
phone
height
weight
name John Lennon
phone 123
height 6' 1"
weight 180
name Sir Paul M.
address Liverpool
weight 175
name George
address 42 Main St.
height 71"
weight 185 lbs
name Ringo Starr
address Penny Lane
phone 456 789
次の出力を生成します。
name address phone height weight
John Lennon 123 6' 1" 180
Sir Paul M. Liverpool 175
George 42 Main St. 71" 185 lbs
Ringo Starr Penny Lane 456 789
値が15文字以上の場合、対応する列はオフになります。これは改善することができます。