このようなテキストファイルがあります。
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
)