次のようなテキストファイルがあります
foo bar baz
1 a alpha
2 b beta
3 c gamma
awk を使用して、1 や 3 などの特定の列を で印刷できます{print $1, $3}
が、代わりに のように列のヘッダーを指定して、印刷する列を指定したいと思います{print $foo, $baz}
。これは、ファイルを開いて手動で列を数えてどの列がどの列であるかを確認する必要がなくなり、列番号や順序が変わってもスクリプトを更新する必要がなくなるため便利です。awk (または別のシェル ツール) を使用してこれを行うことはできますか?
答え1
awk '
NR==1 {
for (i=1; i<=NF; i++) {
f[$i] = i
}
}
{ print $(f["foo"]), $(f["baz"]) }
' file
foo baz
1 alpha
2 beta
3 gamma
これは非常に便利な慣用句です。私はスプレッドシートに大量のデータを持っており、異なるスプレッドシートには私が興味を持っている共通の列のサブセットがあるかもしれませんが、すべてのスプレッドシートで同じ順序である必要はなく、その前または間に同じ数の列があるわけでもありません。そのため、それらを CSV または同様の形式でエクスポートし、列番号ではなく列名を使用して awk スクリプトを実行するだけで済むことは非常に貴重です。
答え2
を求めていますawk
が、これにはより専門的なツール を使用することもできます: csvtool
。
csvtool -t ' ' -u ' ' namedcol foo,baz file
または
csvtool -t ' ' -u ' ' col 1,3 file
答え3
ファイルがTSV(「タブ区切り値」)ファイルであると仮定すると、csvkit
:
$ csvcut -t -c foo,baz file.tsv
foo,baz
1,alpha
2,beta
3,gamma
出力は適切にフォーマットされた CSV になりますが、簡単に TSV に戻すことができます。
$ csvcut -t -c foo,baz file.tsv | csvformat -T
foo baz
1 alpha
2 beta
3 gamma
オプション-c
にはcsvcut
数値や範囲も指定でき、並べ替える入力データの列(標準ユーティリティでは見逃しがちな機能cut
)。