我有 2 个文件无法排序。它们每行都有一个单词列表。我正在尝试比较这两个文件并创建一个新文件没有两个文件之间匹配的任何重复行。这意味着,如果在文件 B 中发现文件 A 上的某行,则它不应显示为输出结果。
很多问题和网站在标题中都说“删除重复项”,但实际上却是“合并重复项并显示唯一项”,这两者有很大区别。前者实际上并不是删除重复项,而只是合并重复项。
对于这种特殊情况,我确实需要真正删除它们。因此,如果在两个文件中都找到它们,则结果不会显示它们。
我已经测试过comm
了,但失败了。我还测试了其他几个案例,比如我见过的 awk、grep。这两个文件的规则如下:
- 它们的尺寸不同(线条数量不同)
- 为了确定重复项,它会将整行与另一个文件中的每一行进行比较
- 文件无法排序
以下是有关这些文件的一些信息,它们包含电子邮件列表,每行一封电子邮件。当然,由于它们的大小不同,这并不意味着它们包含的所有电子邮件都相同,但它们确实包含彼此之间所有唯一的电子邮件。只是有些电子邮件可能同时存在于两个文件中。对于电子邮件同时存在于两个文件中的情况,输出结果不应显示这些电子邮件。
答案1
还有更有效的方法,但这里是A解决方案。我不确定您希望如何合并文件。因此,在此解决方案中,将 file1 中的不同行写入新文件,然后将 file2 中的不同行写入新文件。
# remove_dupes.py
from sys import argv
infile1 = open( str(argv[1]), "r" )
infile2 = open( str(argv[2]), "r" )
try:
outfile = open( str(argv[3]), "w" )
except (IndexError):
outfile = open( 'out', "w" )
if1_arr = infile1.readlines()
if2_arr = infile2.readlines()
tmp_arr = if2_arr
exclude = []
for line in if1_arr:
if line in if2_arr:
exclude.append(line)
else:
outfile.write(line)
for line in if2_arr:
if line not in exclude:
outfile.write(line)
infile1.close()
infile2.close()
outfile.close()
跑步:
python3 remove_dupes.py <file1> <file2> <output_file>
如果您想将其转变为更快的命令行工具,请将脚本移至长期位置,并将以下行添加到您的 .bashrc、.bash_aliases、.zshrc 或等效文件中。
alias mydiff='python3 <path_to_script> '
您可以将“mydiff”替换为您想要的任何名称。之后,您可以使用以下命令运行脚本:
mydiff <file1> <file2> <output_file>
答案2
简单的解决方案
diff --suppress-common-lines fileB fileC
我用目录中的文件名测试了这一点
$ ls *c* > fileC $ ls *b* > fileB
我使用该
sdiff
工具并排显示了两个文件之间的差异。以下是前几行ACM Queue - Databases Only.recipe < ACM Queue Magazine Database Only.recipe < acm_queue.txt < blighted.csv blighted.csv Brave Passwords_4.csv Brave Passwords_4.csv conda_history.txt < conda_install_altair.log2~ < copied.url < copy_in.sh <
我发现有两句共同的
blighted.csv
话Brave Passwords_4.csv
diff --suppress-common-lines fileB fileC
显示文件减去公共行
去测试
$ grep "blighted.csv" fileB blighted.csv $ grep "blighted.csv" fileC blighted.csv $ diff --suppress-common-lines fileC fileB | grep "blighted.csv" $ (no output)
最后一个帮助——删除 diff 应用于输出的编辑标记
diff --suppress-common-lines fileB fileC | grep "^<\|^>" | sed "s/^. //g"