按标题名称打印 awk 中的列

按标题名称打印 awk 中的列

我有一个像这样的文本文件

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

选项-ccsvcut可以采用数字和范围,也可以用于改编输入数据的列(我在标准实用程序中经常错过的功能cut)。

相关内容