打印与命令行中的字符串匹配的列名

时间:2011-05-01 03:49:57

标签: bash awk argv

我想在awk或cut命令中输入字符串名称(即“COL2”),并打印与该列标题字符串匹配的列。

数据文件如下所示:

COL1 COL2 COL3 COL4 COL5 COL6

a a b d c f

a d g h e f

c v a s g a

如果我通过COL3,我希望它打印第三列等等。我认为awk可能是最容易使用的东西,但切割也可以。我只是不确定如何去做。

6 个答案:

答案 0 :(得分:7)

上述问题的Awk 1班轮(如果您有兴趣):

awk -v col=COL2 'NR==1{for(i=1;i<=NF;i++){if($i==col){c=i;break}} print $c} NR>1{print $c}' file.txt

awk -v col=COL3 'NR==1{for(i=1;i<=NF;i++){if($i==col){c=i;break}} print $c} NR>1{print $c}' file.txt

只需使用-vcol=标记传递列名COL1,COL2,COL3等。

答案 1 :(得分:2)

稍微修改了anubhava帖子, 对于多列

awk -vcol1="COL2" -vcol2="COL6" 'NR==1{for(i=1;i<=NF;i++){if($i==col1)c1=i; if ($i==col2)c2=i;}} NR>0{print $c1 " " $c2}' file.txt

当NR&gt; 1不打印列标题时。这被修改为NR> 0,它应该打印带有标题名称的列。

答案 2 :(得分:2)

请注意,如果指定的列不存在,则第一个解决方案会打印出整个文件。如果发生这种情况,要输出警告消息,请尝试

awk -v col=NoneSuch 'NR==1{for(i=1;i<=NF;i++){if($i==col){c=i;break}}   if (c > 0) {print $c}} else {print "Column " col "does not exist"} NR>1 && c > 0 {print $c}' file1.txt

答案 3 :(得分:1)

有点不清楚你要做什么。

如果您想从数据中获取单个列,请使用substr()

如果要使用参数选择列,请使用

之类的内容
BEGIN { mycol = ARGV[1] ; }
      { print $mycol }

更新

嗯,你想要通用的列名吗?

好的,我们假设您的数据组织如下:

 XXXXX YYYYY ZZZZZ

并且您要将列命名为“harpo”,“groucho”和“zeppo”,列名称位于ARGV[1]

 BEGIN { cols["harpo"] = 1; cols["groucho"] = 2; cols["zeppo"] = 3; }
       { print $cols[ARGV[1]]   }

第二次更新

是的,这个技巧会做到这一点。将“harpo”等替换为“COL1”,“Col2”等。

答案 4 :(得分:0)

column是您声明的变量,它是您想要从shell中获取的列。您使用awk's -v选项

传递了它
column=3
awk -vcol="$column" '{print $col}' file

答案 5 :(得分:-1)

当你说“传递一个字符串”到awk时,我想你想在命令行上给出字符串。一种选择是使用-v功能来定义变量

$ gawk -f columnprinter.awk -v col=thecolumnnameyouwant

或者,您可以将内置变量ARGV用作Charlie explains

这只留下了形成数组以将列名与列号相关联的问题。如果输入的第一行包含列名(一个常见的约定),这变得非常容易。

使用

NR==1{...}

处理第一列以获取映射

NR==1{
   colnum=-1;
   for(i=1; i<=NF; i++)
     if ($i == col) {
        colnum=i
        break
     }
}

你可以使用

{
  print $colnum
}