ヘッダー名でawkの列を印刷する

ヘッダー名でawkの列を印刷する

次のようなテキストファイルがあります

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)。

関連情報