Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
列数未知的linux grep模式_Linux_Bash_Awk_Sed_Grep - Fatal编程技术网

列数未知的linux grep模式

列数未知的linux grep模式,linux,bash,awk,sed,grep,Linux,Bash,Awk,Sed,Grep,我有一个包含许多行和列的文本文件,我想用“列名”grep一列 M121 M125 M123 M124 M131 M126 M211 N 0.41463252 1.00296561 -0.1713496 0.15923644 -1.49682602 -1.9478695 1.45223392 … -0.46775802 0.14591103 1.122446 0.83648981 -0.3038532 -1.1841548

我有一个包含许多行和列的文本文件,我想用“列名”grep一列

    M121    M125    M123    M124    M131    M126    M211    N
0.41463252  1.00296561  -0.1713496  0.15923644  -1.49682602 -1.9478695  1.45223392  …
-0.46775802 0.14591103  1.122446    0.83648981  -0.3038532  -1.1841548  2.18074729  …
0.67736835  2.12969375  -0.8187298  0.13582824  -1.49290987 -0.6798428  1.04353114  …
0.08673344  -0.40437672 1.8441559   -0.63679375 0.47998832  0.1702844   0.54029264  …
-0.32606297 -0.95551833 0.6157599   0.02819133  1.44818627  -0.9528659  0.09207864  …
-0.51781121 0.88806507  -0.2913757  -0.00463802 0.05037374  0.953773    0.01244763  …
-0.25724472 0.05119051  0.2109025   -0.26083822 -0.52094072 -0.938595   -0.01275275 …
1.94348766  -1.83607523 1.2010512   -0.54109756 -0.88323831 -0.6263788  -0.96973544 …
0.1900408   -0.61025656 0.4586306   -0.69181051 -0.90713834 0.3589271   0.6870383   …
0.54866057  -0.03861159 -1.505861   0.54871682  -0.24602601 -0.3941754  0.85673905  …
例如,我想grep M211列,但我不知道列数。我试过:

awk '$i == "M211"' filename or  awk '$0 == "M211"' filename
awk:非法字段$(),名称为“i” 输入记录编号1,文件名 源行1号


有什么解决办法吗?谢谢。

awk
解决方案-迭代输入文件第一行的列名,并保存与所需模式匹配的列号。然后打印该列。如果未找到匹配项,则无输出

$ awk 'NR==1{ for(i=1;i<=NF;i++){if($i=="M125")c=i;} if(c==0)exit; }
       {print $c}' ip.txt
M125
1.00296561
0.14591103
2.12969375
-0.40437672
-0.95551833
0.88806507
0.05119051
-1.83607523
-0.61025656
-0.03861159
  • @i=grep{$F[$\]eq“M123”}0..$\F如果头行的$.==1
    ,则获取列值与字符串匹配的索引
    M123
  • if退出@i
    如果未找到匹配项,则退出
  • 打印@F[@i]
    打印匹配的列
  • 假设只有一个列匹配
对于多个匹配,请使用

perl -lane '@i = grep {$F[$_] =~ /^(M121|M126)$/} 0..$#F if $.==1; exit if !@i;
            print join " ", @F[@i]' ip.txt
awk中的另一个:

$ awk 'NR==1 {for(i=NF;i>0;i--) if($i=="M125") break; if(!i) exit} {print $i}' file
M125
1.00296561
0.14591103
2.12969375
-0.40437672
-0.95551833
0.88806507
0.05119051
-1.83607523
-0.61025656
-0.03861159
解释:

NR==1 {                       # for the first record
    for(i=NF;i>0;i--)         # iterate fields backwards for change
        if($i=="M125") break  # until desired column, remember i
    if (!i) exit              # if column not found, exit
} 
{print $i}                    # print value from ith field

如果您更熟悉Python:

import csv
column_name = "M125"
with open("file", "rb") as f:
  data_dict = csv.DictReader(f, delimiter=" ")
  print column_name
  for item in data_dict:
    print item[column_name]

要按名称而不是数字对列(awk中的“字段”)执行任何操作,应首先创建一个数组,将字段名称映射到数字,然后使用按字段名称索引的数组访问字段,而不是直接按字段编号访问字段:


$awk'NR==1{(i=1;ithanks,那么perl或python更容易进行上述操作吗?对于这个问题没有太大区别-awk已经足够好了,并且可以用于大多数类似unix的操作系统。但是如果您有其他文本操作和自动化,python/perl可能会更好。否,awk可以用于所有unix安装,而您不是对于其他文本操作,请使用python或perl。如果您正在执行文本操作以外的操作,请使用python或perl。我不同意,即使对于文本操作,python/perl也涵盖了更广泛的选项和std+第三方模块,以使其更容易。我理解您的观点,但您的基础是您对awk不太了解。30+多年来,我一直在多个领域中操纵文本并帮助他人这么做,但我从未发现python或perl在这项任务中有任何用处。也许我还没有遇到过一些边缘案例,但总的来说,这样说肯定是错误的“如果你有其他的文本操作和自动操作,python/perl可能会更好”这个缺陷的简单修复:
awk'NR==1{for(i=1;i NF)exit}{print$i}文件
@Sundeep我正试图保存字节…对于较短的
if()
?:DBack to original,所有这些字节!:(为什么你会选择一个列名M211作为“grep”,而这个列名在你的示例输入中并不存在?@EdMorton我后面有很多列,其中一列是M211,如果我选择M121或M125,恐怕我会得到的答案是awk'$1==“M121”'filename或awk'$2=“M125”“'文件名,这不是我想要的答案。我希望得到的答案是,我不知道列数,但可以通过'列名'来选择列。谢谢。为您的示例选择不存在的列名有何帮助?您缺少在此处提问所需的预期输出(请参阅)因为给出您发布的示例输入和命令行的预期输出是无效的。给我们一个命令进行测试,但如果您提供了要测试的输入,则不会产生任何输出是没有意义的-选择一个确实存在的值,这样您就可以在您的问题中显示有意义的预期输出,并且我们有一些具体的测试依据。现在我们只是在猜测你想要的结果。@EdMorton这很有帮助!很好,现在如果你的问题是按照我的建议去做的话,那么它将包含获得投票的必要条件,并有助于澄清你的要求。
import csv
column_name = "M125"
with open("file", "rb") as f:
  data_dict = csv.DictReader(f, delimiter=" ")
  print column_name
  for item in data_dict:
    print item[column_name]
$ awk 'NR==1{for (i=1;i<=NF;i++) f[$i]=i} {print $(f["M124"])}' file
M124
0.15923644
0.83648981
0.13582824
-0.63679375
0.02819133
-0.00463802
-0.26083822
-0.54109756
-0.69181051
0.54871682
$ awk -v c=M124 'NR==1{for (i=1;i<=NF;i++) f[$i]=i} {print $(f[c])}' file
M124
0.15923644
0.83648981
0.13582824
-0.63679375
0.02819133
-0.00463802
-0.26083822
-0.54109756
-0.69181051
0.54871682
$ awk -v cols='M129 M124' 'NR==1{for (i=1;i<=NF;i++) f[$i]=i; n=split(cols,c)} {for (i=1;i<=n;i++) printf "%s%s", $(f[c[i]]), (i<n ? OFS : ORS)}' file
M129 M124
1.45223392 0.15923644
2.18074729 0.83648981
1.04353114 0.13582824
0.54029264 -0.63679375
0.09207864 0.02819133
0.01244763 -0.00463802
-0.01275275 -0.26083822
-0.96973544 -0.54109756
0.6870383 -0.69181051
0.85673905 0.54871682