从文件中获取模式,与另一个文件的列进行比较,使用awk打印匹配的行

我本质上喜欢结合的力量

grep -f 

 awk '{ if($2=="this is where I'd like to input a file of fixed string patterns") print $0}' 

也就是说,我想用模式input文件(文件2)search文件的特定列(文件1)。 如果find一个匹配:

 > outputfile.txt 

从以前的post来看,这条awk线非常接近:

 awk 'NR==FNR{a[$0]=1;next} {n=0;for(i in a){if($0~i){n=1}}} n' file1 file2 

取自使用ack或awk或者比grep更好的方法从另一个文件中获取模式?

但它不会search文件1的特定列。我也可以使用其他工具。

你发现的例子确实非常接近你想要的,唯一的区别是你不想匹配整条线( $0 )。

修改它是这样的:

 awk 'NR==FNR { pats[$0]=1; next } { for(p in pats) if($2 ~ p) { print $0; break } }' patterns file 

如果你只需要一个固定的字符串匹配,可以使用index()函数,即用index($2, p)替换$2 ~ p index($2, p)

你也可以提供列号作为awk的参数,例如:

 awk -v col=$col 'NR==FNR { pats[$0]=1; next } { for(p in pats) if($col ~ p) { print $0; break } }' patterns file 

编辑 – 整个字段匹配

您可以使用==运算符完成此操作:

 awk -v col=$col 'NR==FNR { pats[$0]=1; next } { for(p in pats) if($col == p) { print $0; break } }' patterns file 

这是使用awk

 awk 'BEGIN { while(getline l < "patterns.txt") PATS[l] } $2 in PATS' file2 

其中file1是您正在搜索的文件,而patterns.txt是每个文件具有一个确切模式的文件。 隐含的{print}已经被省略,但是你可以添加它并做任何你喜欢的事情。

$2 in PATS的条件$2 in PATS是正确的,第二列恰恰是其中的一种模式。

如果要将patterns.txt视为正则表达式匹配,请将其修改为

 ok=0;{for (p in PATS) if ($2 ~ p) ok=1}; ok 

因此,例如,要对patterns.txt中的所有正则表达式测试$2 ,并在第二列匹配的情况下打印第三列:

 awk 'BEGIN { while(getline l < "patterns.txt") PATS[l] } ok=0;{for (p in PATS) if ($2 ~ p) ok=1}; ok {print $3}' < file2 

这里是perl的一个版本。 与awk版本类似,只是它使用regexps而不是字段。

 perl -ne 'BEGIN{open $pf, "<patterns.txt"; %P=map{chomp;$_=>1}<$pf>} /^\s*([^\s]+)\s+([^\s]+).*$/ and exists $P{$2} and print' < file2 

除此之外:

 BEGIN{ open $pf, "<patterns.txt"; %P = map {chomp;$_=>1} <$pf>; } 

将您的模式文件读入具有%P的快速查找。

 /^\s*([^\s]+)\s+([^\s]+).*$/ and # extract your fields into $1, $2, etc exists $P{$2} and # See if your field is in the patterns hash print; # just print the line (you could also # print anything else; print "$1\n"; etc) 

如果你的输入文件是制表符分隔的(当你知道只有一个字段间的选项卡),它会略微缩短。 以下是一个与第5列相匹配的示例:

  perl -F"\t" -ane ' BEGIN{open $pf, "<patterns.txt"; %P=map{chomp;$_=>1}<$pf>} exists $P{$F[4]} and print ' file2 

这要归功于perl的-F操作符,它告诉perl根据分隔符( \t在这个例子中)自动分割成列。 请注意,因为perl数组从0开始,所以$F[4]是第5个字段。

我不太清楚在这种情况下列的区别。 你处理某种CSV文件? 你在照顾正则表达式列表文件中的列分隔符? 如果文件中没有由特定分隔符分隔的不同列,则可以使用grep

 grep -o -f file2 file1 

如果列是一个问题,也许是这样的:

 grep -o "[^,]*" file1 | grep -f file2 

在哪里,是分隔符。