有两个名为“a.txt”和“b.txt”的文件都有一个单词列表。现在我想检查哪些单词在"a.txt"中是多余的,而不是在"b.txt"中。
我需要一个有效的算法,因为我需要比较两个字典。
有两个名为“a.txt”和“b.txt”的文件都有一个单词列表。现在我想检查哪些单词在"a.txt"中是多余的,而不是在"b.txt"中。
我需要一个有效的算法,因为我需要比较两个字典。
如果你安装了 vim,试试这个:
vimdiff file1 file2
或者
vim -d file1 file2
你会发现它很棒。
对它们进行排序并使用comm
:
comm -23 <(sort a.txt) <(sort b.txt)
comm
比较(排序的)输入文件,默认输出三列:a 唯一的行,b 唯一的行,以及两者中都存在的行。通过指定-1
,-2
和/或-3
您可以抑制相应的输出。因此comm -23 a b
仅列出 a 唯一的条目。我使用<(...)
语法对文件进行动态排序,如果它们已经排序,则不需要它。
如果您更喜欢 diff 输出样式git diff
,可以将其与--no-index
标志一起使用来比较不在 git 存储库中的文件:
git diff --no-index a.txt b.txt
使用几个文件,每个文件大约有 200k 文件名字符串,我对(使用内置time
命令)这种方法与这里的其他一些答案进行了基准测试:
git diff --no-index a.txt b.txt
# ~1.2s
comm -23 <(sort a.txt) <(sort b.txt)
# ~0.2s
diff a.txt b.txt
# ~2.6s
sdiff a.txt b.txt
# ~2.7s
vimdiff a.txt b.txt
# ~3.2s
comm
似乎是迄今为止最快的,而git diff --no-index
似乎是 diff 样式输出的最快方法。
更新 2018-03-25您实际上可以省略该--no-index
标志,除非您在 git 存储库中并且想要比较该存储库中未跟踪的文件。从手册页:
这种形式是比较文件系统上给定的两个路径。当在 Git 控制的工作树中运行命令并且至少有一个路径指向工作树之外,或者在 Git 控制的工作树之外运行命令时,您可以省略 --no-index 选项。
试试sdiff
( man sdiff
)
sdiff -s file1 file2
您可以使用diff
linux 中的工具来比较两个文件。您可以使用--changed-group-format和--unchanged-group-format选项来过滤所需的数据。
以下三个选项可用于为每个选项选择相关组:
'%<' 从 FILE1 获取行
'%>' 从 FILE2 获取行
''(空字符串)用于从两个文件中删除行。
例如:diff --changed-group-format="%<" --unchanged-group-format="" file1.txt file2.txt
[root@vmoracle11 tmp]# cat file1.txt
test one
test two
test three
test four
test eight
[root@vmoracle11 tmp]# cat file2.txt
test one
test three
test nine
[root@vmoracle11 tmp]# diff --changed-group-format='%<' --unchanged-group-format='' file1.txt file2.txt
test two
test four
test eight
您还可以使用:colordiff:用颜色显示 diff 的输出。
关于vimdiff:它允许您通过 SSH 比较文件,例如:
vimdiff /var/log/secure scp://192.168.1.25/var/log/secure
摘自:http ://www.sysadmit.com/2016/05/linux-diferencias-entre-dos-archivos.html
使用comm -13
(需要排序的文件):
$ cat file1
one
two
three
$ cat file2
one
two
three
four
$ comm -13 <(sort file1) <(sort file2)
four
这是我的解决方案:
mkdir temp
mkdir results
cp /usr/share/dict/american-english ~/temp/american-english-dictionary
cp /usr/share/dict/british-english ~/temp/british-english-dictionary
cat ~/temp/american-english-dictionary | wc -l > ~/results/count-american-english-dictionary
cat ~/temp/british-english-dictionary | wc -l > ~/results/count-british-english-dictionary
grep -Fxf ~/temp/american-english-dictionary ~/temp/british-english-dictionary > ~/results/common-english
grep -Fxvf ~/results/common-english ~/temp/american-english-dictionary > ~/results/unique-american-english
grep -Fxvf ~/results/common-english ~/temp/british-english-dictionary > ~/results/unique-british-english
您还可以使用:
sdiff file1 file2
在终端中并排显示差异!
问题的最佳答案是,我使用它(包含在 linux 中) diff a.txt b.txt | grep '<'
扩音器 < extra from a.txt to b.txt :) 意味着 b.txt 没有它们
diff a.txt b.txt | grep '>' 这将给出 a.txt 没有的东西,但这不是问题:)
diff a.txt b.txt | grep '<'
然后可以管道切割以获得干净的输出
diff a.txt b.txt | grep '<' | cut -c 3
使用 awk 。测试文件:
$ cat a.txt
one
two
three
four
four
$ cat b.txt
three
two
one
awk:
$ awk '
NR==FNR { # process b.txt or the first file
seen[$0] # hash words to hash seen
next # next word in b.txt
} # process a.txt or all files after the first
!($0 in seen)' b.txt a.txt # if word is not hashed to seen, output it
输出重复:
four
four
为避免重复,请将 a.txt 中每个新遇到的单词添加到seen
哈希中:
$ awk '
NR==FNR {
seen[$0]
next
}
!($0 in seen) { # if word is not hashed to seen
seen[$0] # hash unseen a.txt words to seen to avoid duplicates
print # and output it
}' b.txt a.txt
输出:
four
如果单词列表以逗号分隔,例如:
$ cat a.txt
four,four,three,three,two,one
five,six
$ cat b.txt
one,two,three
你必须多跑几圈(for
循环):
awk -F, ' # comma-separated input
NR==FNR {
for(i=1;i<=NF;i++) # loop all comma-separated fields
seen[$i]
next
}
{
for(i=1;i<=NF;i++)
if(!($i in seen)) {
seen[$i] # this time we buffer output (below):
buffer=buffer (buffer==""?"":",") $i
}
if(buffer!="") { # output unempty buffers after each record in a.txt
print buffer
buffer=""
}
}' b.txt a.txt
这次输出:
four
five,six