サンプル
wolf@linux:~$ awk {print} file.txt
a b
b c
c d
wolf@linux:~$
データが非常に小さいので、これは簡単です。
wolf@linux:~$ awk 'BEGIN {print " " 1 " " 2} {print NR,$0}' file.txt
1 2
1 a b
2 b c
3 c d
wolf@linux:~$
より大きなデータのための同様の解決策はありますか?ヘッダーを手動で印刷するのではなく、部分的にfor loop
同じものを使用するつもりです。BEGIN {print " " 1 " " 2}
答え1
このBEGIN
部分は入力ファイルが開かれる前に実行されるため、for loop
入力の最初の行をまだ読み取っていないため、Thereを実行しても役に立たないため、繰り返すフィールドの数がわかりません。 1つを追加しない限り、getline
全く異なるウォーム缶です(参照http://awk.freeshell.org/AllAboutGetline)。
awk
フィールドコンテンツを作成し、スペースを使用してフォーマットしますcolumn
。たとえば、次のようになります。
$ awk '
NR==1 { for (i=1; i<=NF; i++) printf " %s", i; print "" }
{ print NR, $0 }
' file | column -s' ' -t
1 2
1 a b
2 b c
3 c d
入力ファイルにフィールド間に複数のスペースまたはタブがある場合は、awkスクリプトの最後の行{ print
を{ $1=$1; print
。
答え2
tbl
必要なスキーマに基づいてテーブルを生成する groff コードを生成する groff ラッパーを使用してテーブルを生成できます。
ここでは、データに基づいてawkユーティリティを使用してgroff組版ユーティリティのコードを生成するtblユーティリティのコードを動的に生成します。
< file \
awk '
BEGIN {
OFS = "@"
print ".TS"
print "box,tab(", ");"
}
!NF {next}
NR==1 {
fx(" ", "c", "c", ".")
fx(OFS)
}
{ $1 = NR OFS $1 };1
END { print ".TE" }
function fp(str, sep) {
printf "%s%s", sep, str
}
function fx(sep, a, b, c, i) {
fp(a)
for (i=1; i<=NF; i++)
fp(b""?b:i, sep)
fp("\n", c)
}
' - | tbl - | groff -Tascii | grep .
出力:
+----------+
| 1 2 |
|1 A B |
|2 B C |
|3 C D |
+----------+
答え3
forループを使用してフィールドを繰り返すことができます。 NR は現在の行番号、NF はその特定の行のフィールド数です。
{ printf ("%4d", NR);
for (f = 1; f <= NF; ++f) printf (" %-6s", $f);
printf ("\n");
}
ヘッダーの場合は、最初の行に表示する列数が見つかるまで待つ必要があります。だからこれ今後前のコード。フィールドの内容を表す$ fではなく、f自体をラベルとして印刷します。
NR == 1 { printf ("%4d", NR);
for (f = 1; f <= NF; ++f) printf (" %-6s", f);
printf ("\n");
}
ソートを維持するには、最大フィールド幅を見つける必要があります。各 %-6 は、「左揃えで最大 6 文字のスペースで埋められる文字列フィールド」を意味します。
編集:高度なバージョンでは、すべてのデータを[NR、NF]でインデックス付けされた2D配列に保存し、ENDブロックとして出力できます。その後、2つのことをさらに実行できます。
(1)各列のセルの最大幅を見つけ、列の実際の幅を使用して%-10s形式を変更します。
(2)各列のすべてが数値の場合は、対応する%sを変更して値を右揃えにします。