【问题标题】:Search and print specific columns from tab delimited file?从制表符分隔的文件中搜索和打印特定列?
【发布时间】:2015-03-10 03:47:51
【问题描述】:

我可以使用 awk 打印文件中的第 n 列; cut 命令也可以做类似的事情.. 但我要求根据其名称获取列,例如:

col1 col2 col3 col4
2 5 3 1
6 4 7 1 
3 6 5 9
7 9 7 8

如果我给出一个列名列表作为输入:例如col1, col3(将是一个很长的列名列表,所以如果输入可以是一个数组会有所帮助)

输出将是

col1 col3
2 3
6 7 
3 5
7 7

有谁知道我如何在 bash 中做到这一点?

【问题讨论】:

  • 将第一行(标题)读入数组:array=( $(head -n+1 filename) )。然后,您可以循环遍历从匹配名称中选择要打印的字段编号的数组。

标签: bash awk


【解决方案1】:
$ awk -v s="col1 col3" 'BEGIN{split(s,v," ");for (i=1;i<=length(v);i++)a[v[i]]=1} NR==1{split($0,b,"\t")} {for (i=1;i<=NF;i++)if (b[i] in a)printf "%s\t",$i;print""}' file
col1    col3
2       3
6       7
3       5
7       7

工作原理

  • -v s="col1 col3"

    定义一个 awk 变量 s,其中包含您要保留的列的空格分隔列表。

  • BEGIN{split(s,v," ");for (i=1;i&lt;=length(v);i++)a[v[i]]=1}

    创建一个关联数组a,其键是列名,值是字符串s中的列之一。

  • NR==1{split($0,b,"\t")}

    将列名保存在关联数组b中。

  • for (i=1;i&lt;=NF;i++) if (b[i] in a) printf "%s\t",$i; print""

    对于每一列 i,如果列名 b[i] 在数组 a 中,则打印该列,后跟一个制表符。

    为了结束,print "" 打印一个换行符。

【讨论】:

    【解决方案2】:
    $ cat tst.awk
    BEGIN { FS=OFS="\t" }
    NR==1 {
        for (i=1;i<=NF;i++) {
            if ( match(cols,"(^| )"$i"( |$)") ) {
                colNrs[++numCols] = i
            }
        }
    }
    {
        for (i=1;i<=numCols;i++) {
            printf "%s%s", $(colNrs[i]), (i<numCols?OFS:ORS)
        }
    }
    
    $ awk -v cols="col1 col3" -f tst.awk file
    col1    col3
    2       3
    6       7
    3       5
    7       7
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-11
      • 2011-05-02
      • 1970-01-01
      • 1970-01-01
      • 2012-01-06
      • 1970-01-01
      • 2018-01-04
      • 2012-07-22
      相关资源
      最近更新 更多