使用awk搜索整个文件以匹配字段1

时间:2015-11-06 16:07:09

标签: awk

我有一个像这样的输入文件,里面有很多记录(但它们是用逗号分隔的):

ALBAN SQUARE,SGWAR ALBAN 
HEOL GWYNN,ALBERT STREET
test1,test2                        
ALBERT PLACE,MAES ALBERT                         
ALBERT STREET,STRYD ALBERT                        
ALBERT STREET,HEOL GWYNN                          
HEOL GWYNN,ALBERT STREET
test1,test2

我希望能够在整个文件中搜索field1,如果第一个字段出现在column1或column2中,我希望将此行打印到csv文件。但是,如果它只出现一次我想要打印到另一个csv文件。所以我的输出是:

repeated.csv

HEOL GWYNN,ALBERT STREET                         
ALBERT STREET,STRYD ALBERT                        
ALBERT STREET,HEOL GWYNN
HEOL GWYNN,ALBERT STREET
test1,test2
test1,test2

diff.csv

ALBAN SQUARE,SGWAR ALBAN                         
ALBERT PLACE,MAES ALBERT 

目前重复的输出是:

HEOL GWYNN,ALBERT STREET
test1,test2                        
ALBERT STREET,STRYD ALBERT                        
ALBERT STREET,HEOL GWYNN                          
HEOL GWYNN,ALBERT STREET
test1,test2

我想让匹配在输出中低于另一个,如上所示。

这可以用awk做吗?

我试过了:

BEGIN{ FS=","; } 
{ count[$1]++; 
  if (count[$1] == 1) first[$1] = $0; 
  if (count[$1] == 2) print first[$1]; 
  if (count[$1] > 1) print; 
}
End{ }

2 个答案:

答案 0 :(得分:2)

另一个类似的awk,带有双遍

$ awk -F"\t" 'NR==FNR{a[$1]++;a[$2]++;next} 
              $1 in a{if(a[$1]==1) print > "ones"; 
                      else print > "multi"
                     }' file{,}

结果

$ cat multi
ALBERT STREET   STRYD ALBERT
ALBERT STREET   HEOL GWYNN
HEOL GWYNN      ALBERT STREET

$ cat ones
ALBAN SQUARE    SGWAR ALBAN
ALBERT PLACE    MAES ALBERT

更新

你可以再保存几次击键

$ awk -F"\t" 'NR==FNR{a[$1]++;a[$2]++;next} 
              $1 in a{print > (a[$1]==1?"ones":"multi")}' file{,}

说明:计算第一遍中位置1和2的字段数。第二次检查字段1的计数,如果它恰好是一个输出到"那些"如果它更多的是"多"。

请注意,第二个位置的多个字段计数也会被计算,但如果该值从未出现在第一个位置,则不会在第二个过程中对其进行检查。这简化了逻辑。

答案 1 :(得分:1)

您可以执行以下操作:

awk 'BEGIN{FS=OFS="\t"}
     FNR==NR{for (i=1;i<=NF;i++) a[$i]++; next}
     {file="diff";
      if (a[$1]>1 || a[$2]>1) file="repeated";
      print > file
     }' file file

我假设这些列是制表符分隔的。

请注意,这会使用类似于您所解释的内容。这里的关键是跟踪每个字段在第一个循环中出现的次数。

在第二个循环中,我们检查是否有任何字段出现多次;如果是这样,我们将输出文件设置为&#34;重复&#34; (将其命名为csv1,2或其他);否则,该文件是&#34;差异&#34;。然后,它将该行输出到文件。

测试

$ awk -F"\t" 'FNR==NR{for (i=1;i<=NF;i++) a[$i]++; next} {file="diff"; if (a[$1]>1 || a[$2]>1) file="repeated"; print > file}' a a
$ cat diff
ALBAN SQUARE    SGWAR ALBAN
ALBERT PLACE    MAES ALBERT
$ cat repeated 
ALBERT STREET   STRYD ALBERT
ALBERT STREET   HEOL GWYNN
HEOL GWYNN      ALBERT STREET

使用我在&#34;测试&#34;中提到的单线运行它。部分或将其保存到awk文件中:

$ cat script.awk
BEGIN{FS=OFS="\t"}
     FNR==NR{for (i=1;i<=NF;i++) a[$i]++; next}
     {file="diff";
      if (a[$1]>1 || a[$2]>1) file="repeated";
      print > file
}

$ awk -f script.awk file file