列数未知的linux grep模式
我有一个包含许多行和列的文本文件,我想用“列名”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
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