【问题标题】:Bash retrieve column number from column nameBash 从列名中检索列号
【发布时间】:2015-09-16 15:29:05
【问题描述】:

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

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

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

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

#!/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

有没有办法不使用 for 循环(或者至少清理一下)?

给定脚本的预期输出是:

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

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

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

【问题讨论】:

  • 预期输出是什么?

标签: bash shell awk


【解决方案1】:

这是一个 awk 替代方案:

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

编辑:仅打印列号:

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

【讨论】:

  • 虽然可行,但我主要专注于返回列号:请参阅我在问题中编辑的 i=$(magic...) 行。
  • 确定检查更新的答案以打印给定名称的列号。
【解决方案2】:

另一种有很多管道的选择

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

提取第一行,转置,数字行,查找列名,提取数字

或者,awk 来救援!

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

【讨论】:

    【解决方案3】:
    $ awk -v name='Target' '{for (i=1;i<=NF;i++) if ($i==name) print i; exit}' file
    3
    

    【讨论】:

      猜你喜欢
      • 2010-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-13
      • 1970-01-01
      • 2017-08-21
      • 2013-07-16
      • 1970-01-01
      相关资源
      最近更新 更多