在 linux 终端中比较两个文件

有两个名为“a.txt”“b.txt”的文件都有一个单词列表。现在我想检查哪些单词在“a.txt”中是多余的,而在“b.txt”中不是。

我需要一个有效的算法,因为我需要比较两个字典。

348586 次浏览

对它们进行排序并使用comm:

comm -23 <(sort a.txt) <(sort b.txt)

comm比较(排序)输入文件,默认情况下输出三列:对a唯一的行,对b唯一的行,以及在两者中都存在的行。通过指定-1-2和/或-3,可以抑制相应的输出。因此,comm -23 a b只列出a唯一的条目。我使用<(...)语法对文件进行动态排序,如果它们已经排序,则不需要这样做。

你可以在linux中使用diff工具来比较两个文件。你可以使用——changed-group-format——unchanged-group-format选项来过滤所需的数据。

以下三个选项可用于为每个选项选择相关的组:

  • '%<'从FILE1获取行

  • '%>'从FILE2获取行

  • (空字符串)用于从两个文件中删除行。

例句:diff - changed-group-format = " % & lt; "——unchanged-group-format="" file1.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

使用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

如果你安装了vim,试试这个:

vimdiff file1 file2

vim -d file1 file2

你会发现它棒极了。enter image description here

尝试sdiff (man sdiff)

sdiff -s file1 file2

你也可以使用: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

如果你更喜欢git diff的diff输出样式,你可以使用它和--no-index标志来比较不在git存储库中的文件:

git diff --no-index a.txt b.txt

使用两个文件,每个文件中大约有200k文件名字符串,我(使用内置的__abc0命令)对这种方法与其他一些答案进行了基准测试:

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似乎是diffstyle输出的最快方法。


你实际上可以省略--no-index标志,除非你在git存储库中,想要比较该存储库中未跟踪的文件。从手册页:

此表单用于比较文件系统上给定的两个路径。当在Git控制的工作树中运行命令,并且至少有一个路径指向工作树之外,或者在Git控制的工作树之外运行命令时,可以省略——no-index选项。

另外,不要忘记mcdiff - GNU午夜指挥官的内部差异查看器。

例如:

mcdiff file1 file2

享受吧!

使用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

你必须做一些额外的圈(forloops):

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

你还可以使用:

sdiff file1 file2

在终端内并排显示差异!

diff a.txt b.txt | grep '<'

然后管道可以切割为一个干净的输出

diff a.txt b.txt | grep '<' | cut -c 3