7

我基本上想结合

grep -f 

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

也就是说,我想使用模式输入文件(文件 2)搜索文件(文件 1)的特定列。如果简单地找到匹配项:

> outputfile.txt

从上一篇文章来看,这条 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 更好的方式从另一个文件中获取模式?

但它不会搜索文件 1 的特定列。我也对其他工具持开放态度。

4

3 回答 3

4

您找到的示例确实与您想要的非常接近,唯一的区别是您不想匹配整行($0)。

将其修改为如下内容:

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

如果您只需要固定字符串匹配,请改用该index()函数,即替换$2 ~ pindex($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
于 2013-01-23T08:37:34.477 回答
3

这是使用awk

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

file1您正在搜索的文件在哪里,并且patterns.txt是每个文件具有一个精确模式的文件。隐式{print}已被省略,但您可以添加它并在那里做任何您喜欢的事情。

$2 in PATS如果第二列恰好是模式之一,则条件为真。

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

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

因此,例如,要$2针对 中的所有正则表达式进行测试,如果第二列匹配patterns.txt,则打印 第三列:

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版本类似,只是它使用正则表达式而不是字段。

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>;
}

将您的模式文件读入 has%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 个字段。

于 2013-01-23T01:49:33.147 回答
0

我不太确定在这种情况下列的区别在哪一部分起作用。您是否处理某种 csv 文件?您是否处理正则表达式列表文件中的列分隔符?如果文件中没有由某些分隔符分隔的不同列,则可以使用grep

grep -o -f file2 file1

如果列是一个问题,可能是这样的:

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

分隔符在哪里,

于 2013-01-23T02:08:42.677 回答