我有两个文本文件,例如
A
1111|100|11/11/1111|a
2222|200|11/11/1111|a
3333|300|11/11/1111|a
4444|400|11/11/1111|a
乙
1111|100|11/11/1111|a
1111|100|11/11/1111|a
2222|200|11/11/1111|a
3333|300|11/11/1111|a
5555|500|11/11/1111|a
我用过下面的命令
awk -F"|" '{ printf "%4s|%3s|\n",$1,$2 }' a | grep -v -f /dev/stdin b
哪个输出....
5555|500|11/11/1111|a
预期产出为
1111|100|11/11/1111|a
5555|500|11/11/1111|a
我怎样才能做到这一点grep
或awk
答案1
grep
在这里不适合,因为它用于提取与某种形式的正则表达式匹配的单独行(而不是用于真正比较文件)。它无法返回一个匹配项并丢弃另一个匹配项(文件的前两行b
)。
你可以使用comm
:
$ comm -13 a b
1111|100|11/11/1111|a
5555|500|11/11/1111|a
请注意,comm
依赖于排序的输入数据。
comm
上面的命令用于丢弃-13
默认输出中的第一列和第三列。默认情况下,它将输出仅在第 1 列中的第一个文件中找到的行、仅在第 2 列中的第二个文件中找到的行以及最后一列中的公共行(请参阅手册comm
默认情况下,它将输出仅在第 1 列第一个文件中找到的行、仅在第 2 列第二个文件中找到的行以及最后一列中的公共行(请参阅系统上的标准实用程序):
$ comm a b
1111|100|11/11/1111|a
1111|100|11/11/1111|a
2222|200|11/11/1111|a
3333|300|11/11/1111|a
4444|400|11/11/1111|a
5555|500|11/11/1111|a
答案2
使用 GNU awk for arrays of arrays 和 ARGIND 比较任意数量的未排序文件的更通用方法:
$ cat tst.awk
BEGIN { OFS="\t" }
{ cnt[$0][ARGIND]++ }
END {
for (str in cnt) {
for (fileNr=1; fileNr<=ARGIND; fileNr++) {
printf "%d%s", cnt[str][fileNr], OFS
}
print str
}
}
$ awk -f tst.awk a b
1 2 1111|100|11/11/1111|a
1 1 2222|200|11/11/1111|a
1 1 3333|300|11/11/1111|a
1 0 4444|400|11/11/1111|a
0 1 5555|500|11/11/1111|a
上面显示了所有文件中的每个唯一字符串以及给定字符串在第一个文件中出现的次数、在第二个文件中出现的次数等。
要获得您想要的输出,可以简单地执行以下操作:
$ awk -f tst.awk a b | awk '$2>$1' | cut -f3-
1111|100|11/11/1111|a
5555|500|11/11/1111|a