我有一個像這樣的文字文件
foo bar baz
1 a alpha
2 b beta
3 c gamma
我可以使用 awk 來列印某些列,例如 1 和 3 {print $1, $3}
,但我想透過指定列標題來指定要列印的列,例如{print $foo, $baz}
.這很有用,因此我不必打開文件並手動計算列數來查看哪一列是哪一列,並且如果列號或順序發生變化,我也不必更新腳本。我可以使用 awk (或其他 shell 工具)來完成此操作嗎?
答案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
)。