Bash 从列名中检索列号

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32612859/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 13:34:50  来源:igfitidea点击:

Bash retrieve column number from column name

bashshellawk

提问by Rob

Is there a better way (such as a one liner in AWK) where I can get the column number in a table with headings from a column name? I want to be able to process a column independent of what the column number actually is (such as when another column is added the script will not need to change).

有没有更好的方法(例如 AWK 中的单行),我可以在表格中获取带有列名标题的列号?我希望能够独立于列号实际处理一列(例如,当添加另一列时,脚本将不需要更改)。

For example, given the following table in "table.tsv":

例如,给定“table.tsv”中的下表:

ID  Value   Target  Not Used
1   5   9   11
2   4   8   12
3   6   7   10

I can do a sort on the "Target" column using:

我可以使用以下方法对“目标”列进行排序:

#!/bin/bash
(IFS=$'\t'; read -r; printf "%s\n" "$REPLY"; i=0; for col in $REPLY; do
    ((++i))
    [ "$col" == "Target" ] && break
done; sort -t$'\t' "-k$i,${i}n") < table.tsv

Is there a way to do it without the for loop (or at least clean it up a little)?

有没有办法在没有 for 循环的情况下做到这一点(或者至少稍微清理一下)?

The expected output of the given script is:

给定脚本的预期输出是:

ID      Value   Target  Not Used
3       6       7       10
2       4       8       12
1       5       9       11

However, I was trying to give an example of what I was trying to do. I want to pass/filter my table through several programs so the headings and all columns should be preserved: just have processing occur at each step. In pseudo code, what I would like to do is:

但是,我试图举例说明我正在尝试做的事情。我想通过几个程序传递/过滤我的表格,这样标题和所有列都应该被保留:只需在每一步进行处理。在伪代码中,我想做的是:

print headings from stdin
i=$(magic to determine column position given "Target")
sort -t$'\t' "-k$i,${i}n"  # or whatever processing is required on that column

回答by karakfa

another alternative with a lot of pipes

有很多管道的另一种选择

$ head -1 table | tr -s ' ' '\n' | nl -nln |  grep "Target" | cut -f1

extract first row, transpose, number lines, find column name, extract number

提取第一行,转置,编号行,查找列名,提取编号

Or, awkto the rescue!

或者,awk救命!

$ awk -v RS='\t' '/Target/{print NR; exit}' file.tsv
3

回答by anubhava

Here is an awk alternative:

这是一个 awk 替代方案:

awk -F '\t' -v col='Target' 'NR==1{for (i=1; i<=NF; i++) if ($i == col){c=i; break}}
      {print $c}' file


EDIT:To print column number only:

编辑:仅打印列号:

awk -F '\t' -v col='Target' 'NR==1{for (i=1; i<=NF; i++) if ($i==col) {print i;exit}}' file
3

回答by Ed Morton

$ awk -v name='Target' '{for (i=1;i<=NF;i++) if ($i==name) print i; exit}' file
3