AWK:比较具有不同分隔符的文件的差异

时间:2014-03-31 11:31:33

标签: unix awk

1.txt 
1|2|3
4|5|6
7|3|6

2.txt (double pipe)
1||2||3
4||5||6

expected
7|3|6

我想比较1.txt和2.txt并打印差异。请注意,列数可能每次都有所不同

awk -F"|" 'NR==FNR{a[$0]++;next} !(a[$0])'  2.txt 1.txt

如何修改代码以在每个文件中包含分隔符。

下面的代码仅适用于第一个字段,但我不确定它是如何通过双管道分隔字段的

awk -F"|" 'NR==FNR{a[$1]++;next} !(a[$1])' 2.txt 1.txt

4 个答案:

答案 0 :(得分:1)

一个简单的解决方法是在送到awk之前在第二个文件中挤压双分隔符

awk -F"|" 'NR==FNR{a[$0]++;next} !(a[$0])' <(tr -s '|' < 2.txt) 1.txt

对于您的样本输入,它会产生:

7|3|6

编辑:你断言

awk -F"|" 'NR==FNR{a[$1]++;next} !(a[$1])' 2.txt 1.txt

的工作原理。它不符合你的期望。它仅比较第一个字段而不是整行。

答案 1 :(得分:1)

您可以使用此awk

awk -F"|" 'NR==FNR{gsub(/\|\|/,"|",$0);a[$0]++;next} !(a[$0])' 2.txt 1.txt

答案 2 :(得分:0)

我通常使用bash功能来完成此任务:

diff 1.txt <(sed 's/||/|/g' < 2.txt)

答案 3 :(得分:0)

你可以在gawk中使用regexp作为分隔符,如果你不介意输出是未排序的(如awk中的数组),你可以用一个命令来完成:

gawk  'BEGIN {FS="\\|\\|*"} {gsub(FS,"|") ; a[$0]++} END {for (k in a) {if ( a[k] > 0 ) { print k } } }'
  1. BEGIN {FS="\\|\\|*"} ==&gt;字段分隔符是一个或多个|
  2. {gsub(FS,"|") ; a[$0]++} ==&gt;在每一行上将分隔符|的数量标准化为1并将该行存储在a n数组中,或者如果它已经在a rray中,则增加相关值对它
  3. END {for (k in a) {if ( a[k] > 0 ) { print k } } }最后打印出多次找不到的a个rray元素。