两个文本文件每行只有一个项,如何找到它们之间的差异?

101

我有两个文件:

文件1

dsf
sdfsd
dsfsdf

文件2

ljljlj 
lkklk 
dsf
sdfsd
dsfsdf

我想要显示在文件2中而不在文件1中的内容,所以文件3应该如下所示

ljljlj 
lkklk 
11个回答

168
grep -Fxvf file1 file2

标志的含义:

-F, --fixed-strings
              Interpret PATTERN as a list of fixed strings, separated by newlines, any of which is to be matched.    
-x, --line-regexp
              Select only those matches that exactly match the whole line.
-v, --invert-match
              Invert the sense of matching, to select non-matching lines.
-f FILE, --file=FILE
              Obtain patterns from FILE, one per line.  The empty file contains zero patterns, and therefore matches nothing.

4
选项-n可以添加以对不同的行进行编号。 - boczniak767
有没有办法突出显示每行中不匹配的部分? - PeterVermont
1
使用以下命令可以找到第一个不同之处并打印其行号:grep -m 1 -Fnxvf file1 file2 - Paolo M
在大文件上非常低效。 - Ain Tohvri

61
你可以尝试。
grep -f file1 file2
或者
grep -v -F -x -f file1 file2

4
这样不行。尝试在file2中添加 dsfblah - dogbane
6
你可以使用 grep -F -x 命令来解决这个问题。 - tripleee
3
我认为你的建议值得编辑@tripleee的回答。 - jopasserat
3
请注意文件的顺序很重要。我正在尝试检测一个文件的新添加。我必须写成grep -v -f oldfile newfile,否则它将不会输出任何东西。 - Marvo
2
想象一下:git add file1。git commit。cat file2 > file1。git diff。 - user3451822
krico@ 你能为传递的参数添加解释吗? - Raghvendra

48

您可以使用 comm 命令来比较两个已排序的文件。

comm -13 <(sort file1) <(sort file2)

3
FYI,实际上应该是 comm -1 -3 file1 file2。两个标志 13 合并成一个使用。 - cevaris
comm -23 <(sort file1) <(sort file2) 只会输出 file1 中存在而 file2 中不存在的内容。最好的部分是,file2 中的任何排列方式都可以使用,而 diff 命令则会失败;比如说,如果 file1 包含 1、2、3、4、5,而 file2 包含 1、2、4、5,则 comm 命令可以正确输出 3,而 diff 命令则会出错。 - user1213320

14

我成功地使用了

diff "${file1}" "${file2}" | grep "<" | sed 's/^<//g' > "${diff_file}"

将差异输出到文件。


有什么比使用差异工具更好的方法来查找差异呢,哈哈。与使用grep相比,使用它会有更高的开销吗? - Allison

9
如果你希望以某种特定的顺序来比较它们,你可以使用diff命令。 diff file1 file2 | grep ">"

7
join -v 2 <(sort file1) <(sort file2)

4

我尝试了Luca的答案并稍作改动,结果对我有效。

diff file1 file2 | grep ">" | sed 's/^> //g' > diff_file

注意,在sed中搜索的模式是一个>后跟一个空格。

3
file1
m1
m2
m3
file2 m2 m4 m5
> awk 'NR == FNR {file1[$0]++; next} !($0 in file1)' file1 file2 获取在file2中但不在file1中的内容: m4 m5
> awk 'NR == FNR {file1[$0]++; next} ($0 in file1)' file1 file2 获取同时存在于file1和file2中的内容: m2
> 如何使用awk命令只获取file1中而不在file2中的'm1和m3'? m1 m3

1
一个awk的答案: awk 'NR == FNR {file1[$0]++; next} !($0 in file1)' file1 file2

0
如果你想使用循环,可以尝试这样做:(diff和cmp更有效率。)
while read line
do
    flag = 0
    while read line2
    do
       if ( "$line" = "$line2" )
        then
            flag = 1
        fi
     done < file1 
     if ( flag -eq 0 )
     then
         echo $line > file3
     fi
done < file2

注意:该程序仅提供基本的见解,如果您不想使用诸如diff和comm之类的系统调用,可以使用它来完成一些操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接