![根据个人标准比较两个文件](https://linux22.com/image/179577/%E6%A0%B9%E6%8D%AE%E4%B8%AA%E4%BA%BA%E6%A0%87%E5%87%86%E6%AF%94%E8%BE%83%E4%B8%A4%E4%B8%AA%E6%96%87%E4%BB%B6.png)
我有两个文本文件,例如File1.txt
:
A
B
C
E
和File2.txt
:
C
D
E
其中字母代表线条。
我想找到 中的所有结果File1.txt
,而不是 中的File2.txt
结果。两个文件中的结果有所不同。
这怎么可能做到呢?所以在这种情况下,它应该调用 A 和 B。
答案1
如果它们已排序,请尝试:
comm -23 File1.txt File2.txt
如果它们没有排序,但可以对它们进行排序,请尝试在 bash 中:
comm -23 <(sort File1.txt) <(sort File2.txt)
除非您uniq
或sort -u
File1.txt,否则将输出 File1.txt 中出现次数多于 File2.txt 中出现次数的行。这可能适合也可能不适合您的用例。
如果一个文件已经排序,您可以在大多数 shell 中使用简单的管道,例如:
sort File1.txt | comm -23 - File2.txt
答案2
简化了,感谢@杰夫·夏勒
尝试:
fgrep -vx -f File2.txt File1.txt
这是:查找 File1.txt 中与 File2.txt 中的行不匹配的所有行
我之前不知道的 -x 选项导致匹配需要完整的行。
-v 选项表示显示不匹配的内容。
-f 选项指定文件中后面的行是模式。
答案3
一个快速的 tcsh 脚本:
# arg2linesNOTINarg1.csh:
# tcsh
# LINES FROM ARG2 THAT ARE NOT IN ARG1
#
if ( $#argv < 2 ) then
echo ' set fileWITHavoidedLINES = $1 '
echo ' set fileTOsearch = $2 '
else
set fileWITHavoidedLINES = $1
set fileTOsearch = $2
endif
set genSRCHstr = 'awk '"'"'BEGIN { started=0; } \
{ if (started==0) printf("^%s$",$0); \
else printf("|^%s$",$0) ; started=1 } \
END { printf("\n") } '"'"' '"${fileWITHavoidedLINES}"' '
egrep -v `eval ${genSRCHstr}` $fileTOsearch
可以通过以下方式运行:
tcsh arg2linesNOTINarg1.csh File2.txt File1.txt
如果行太长或者包含空格或制表符等特定字符,则在生成搜索字符串时可能会遇到问题。也许可以修改它来防止这些问题,但这个建议只是一个开始。
答案4
awk
awk 'NR==FNR{a[$1];next}!($1 in a){print $1}' file2.txt file1.txt
输出
A
B