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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5846300/
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-17 23:53:26  来源:igfitidea点击:

print column name that matches string from commandline

bashawkargv

提问by Nick

I want to input a string name (i.e. "COL2") to an awk or cut command and print the column that matches that column header string.

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

the datafile looks like this:

数据文件如下所示:

COL1 COL2 COL3 COL4 COL5 COL6

a a b d c f

a d g h e f

c v a s g a

If I pass in COL3, I want it to print the third column, etc. I'm thinking awk might be the easiest thing to use, but cut may also work. I'm just not sure how to go about doing this.

如果我传入 COL3,我希望它打印第三列,等等。我认为 awk 可能是最容易使用的东西,但 cut 也可以工作。我只是不知道该怎么做。

采纳答案by anubhava

Awk 1 liner for above problem (if you are interested):

上述问题的 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

Just pass your column name COL1, COL2, COL3 etc with -vcol=flag.

只需将您的列名 COL1、COL2、COL3 等与-vcol=标志传递。

回答by bala

a slight modification of anubhavapost on top, for multiple columns

对顶部的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

when NR>1 does not print the column headers. This was modified to NR>0 which should print the columns with header names.

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

回答by AaronB

Note that the first solution prints out the whole file if the named column does not exist. To output a warning message if this occurs try

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

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

回答by Charlie Martin

It's a little unclear what you're trying to do.

有点不清楚你要做什么。

If you want to get the single column from the data, use substr().

如果要从数据中获取单列,请使用substr().

If you want to use an argument to choose the column use something like

如果您想使用参数来选择列,请使用类似

BEGIN { mycol = ARGV[1] ; }
      { print $mycol }

Update

更新

Hmmm, so you want generalized column names?

嗯,所以你想要通用的列名?

Okay, we'll assume that your data is organized like this:

好的,我们假设您的数据是这样组织的:

 XXXXX YYYYY ZZZZZ

and you want to name the columns "harpo", "groucho" and "zeppo", and the column name is in ARGV[1]:

并且您想将列命名为“harpo”、“groucho”和“zeppo”,并且列名在ARGV[1]

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

Second update

第二次更新

Yup, this trick will do it. Replace "harpo" etc with "COL1", "Col2", and so on.

是的,这个技巧可以做到。将“harpo”等替换为“COL1”、“Col2”等。

回答by ghostdog74

say columnis the variable you declared that is the column you want from the shell. You pass it in using awk's-voption

saycolumn是你声明的变量,它是你想要的来自 shell 的列。您使用awk's-v选项传递它

column=3
awk -vcol="$column" '{print $col}' file

回答by dmckee --- ex-moderator kitten

When you say "pass a string" to awk, I guess you want to give the string on the command line. One option is to use the -vfeature for defining variables

当您对 awk 说“传递一个字符串”时,我猜您想在命令行上提供该字符串。一种选择是使用该-v功能来定义变量

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

Alternately you can use the built-in variable ARGVas Charlie explains.

或者您可以使用内置变量ARGV作为查理解释

That only leaves the matter for forming an array to associate column names with column numbers. If the first line of the input contains the column names (a common convention) this becomes pretty easy.

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

Use

NR==1{...}

to process the first column to get the mapping

处理第一列以获取映射

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

which you can use like

你可以像这样使用

{
  print $colnum
}