Linux中两个目录的区别

Err*_*404 295 linux bash diff

我正在尝试查找存在于一个目录中但不存在于另一个目录中的文件,我尝试使用此命令:

diff -q dir1 dir2
Run Code Online (Sandbox Code Playgroud)

上面命令的问题是,它既可以找到文件dir1但不包含在文件中但不在dir2文件dir2dir1,

我试图找到文件,dir1但不是dir2只.

这是我的数据的一个小样本

dir1    dir2    dir3
1.txt   1.txt   1.txt
2.txt   3.txt   3.txt
5.txt   4.txt   5.txt
6.txt   7.txt   8.txt
Run Code Online (Sandbox Code Playgroud)

我想到的另一个问题是如何在单个命令dir1dir2dir3在单个命令中找到文件?

asc*_*pix 390

diff -r dir1 dir2 | grep dir1 | awk '{print $4}' > difference1.txt
Run Code Online (Sandbox Code Playgroud)

说明:

  • diff -r dir1 dir2 显示哪些文件仅在dir1中,哪些文件仅在dir2中,以及两个目录中存在的文件的更改(如果有).

  • diff -r dir1 dir2 | grep dir1 显示哪些文件仅在dir1中

  • awk 仅打印文件名.

  • 我会像`^ dir1`那样'grep`以确保我没有在路径后面出现`dir1`. (5认同)

tok*_*khi 139

这应该做的工作:

diff -rq dir1 dir2
Run Code Online (Sandbox Code Playgroud)

解释选项(通过diff(1)手册页):

  • -r - 递归比较找到的所有子目录.
  • -q - 仅输出文件是否不同.

  • 太好了!但我认为它应该像那样扩展:`diff -rq dir1 dir2 | grep'仅在dir1 /'中 (8认同)
  • 只是关于`-q`选项的注释:手册页只会说"仅输出文件是否不同",而不是如何检查它们是否不同.我仔细阅读了源代码,发现它只检查文件大小以确定差异,而不是实际内容. (5认同)
  • 这是按内容进行比较,但在慢速驱动器上可能需要很长时间. (2认同)

plh*_*lhn 50

comm -23 <(ls dir1 |sort) <(ls dir2|sort)
Run Code Online (Sandbox Code Playgroud)

此命令将为您提供dir1中的文件,而不是 dir2中的文件.

关于<( )签名,您可以将其视为"流程替代".

  • vimdiff使用颜色突出显示提供了更好的视觉比较:`vimdiff &lt;(ls dir1 | sort)&lt;(ls dir2 | sort)` (3认同)

小智 32

进行这种比较的一个好方法是使用findwith md5sum,然后a diff.

例:

使用find列出目录中的所有文件,然后计算出每个文件和管道到一个文件的MD5哈希:

find /dir1/ -type f -exec md5sum {} \; > dir1.txt
Run Code Online (Sandbox Code Playgroud)

对另一个目录执行相同的过程:

find /dir2/ -type f -exec md5sum {} \; > dir2.txt
Run Code Online (Sandbox Code Playgroud)

然后将结果两个文件与"diff"进行比较:

diff dir1.txt dir2.txt
Run Code Online (Sandbox Code Playgroud)

当要比较的两个目录不在同一台机器中并且您需要确保两个目录中的文件相同时,此策略非常有用.

另一个做这项工作的好方法是使用git

git diff --no-index dir1/ dir2/
Run Code Online (Sandbox Code Playgroud)

最好的祝福!


Cat*_*tcu 17

Meld(http://meldmerge.org/)在比较目录和文件中做得很好.

Meld比较目录

  • 它还坚持读取文件内容,因此对于&gt;&gt; 1GB目录几乎没有用。 (3认同)

drr*_*sum 13

vim的DirDiff插件是另一个用于比较目录的非常有用的工具.

vim -c "DirDiff dir1 dir2"
Run Code Online (Sandbox Code Playgroud)

它不仅列出了目录中哪些文件不同,而且还允许您使用vimdiff检查/修改不同的文件.


And*_*kha 11

对所有回复都不满意,因为大多数回复工作得非常慢并且为大型目录产生不必要的长输出,我编写了自己的Python脚本来比较两个文件夹.

与许多其他解决方案不同,它不会比较文件的内容.此外,它不会进入另一个目录中缺少的子目录.因此输出非常简洁,脚本运行速度很快.

#!/usr/bin/env python3

import os, sys

def compare_dirs(d1: "old directory name", d2: "new directory name"):
    def print_local(a, msg):
        print('DIR ' if a[2] else 'FILE', a[1], msg)
    # ensure validity
    for d in [d1,d2]:
        if not os.path.isdir(d):
            raise ValueError("not a directory: " + d)
    # get relative path
    l1 = [(x,os.path.join(d1,x)) for x in os.listdir(d1)]
    l2 = [(x,os.path.join(d2,x)) for x in os.listdir(d2)]
    # determine type: directory or file?
    l1 = sorted([(x,y,os.path.isdir(y)) for x,y in l1])
    l2 = sorted([(x,y,os.path.isdir(y)) for x,y in l2])
    i1 = i2 = 0
    common_dirs = []
    while i1<len(l1) and i2<len(l2):
        if l1[i1][0] == l2[i2][0]:      # same name
            if l1[i1][2] == l2[i2][2]:  # same type
                if l1[i1][2]:           # remember this folder for recursion
                    common_dirs.append((l1[i1][1], l2[i2][1]))
            else:
                print_local(l1[i1],'type changed')
            i1 += 1
            i2 += 1
        elif l1[i1][0]<l2[i2][0]:
            print_local(l1[i1],'removed')
            i1 += 1
        elif l1[i1][0]>l2[i2][0]:
            print_local(l2[i2],'added')
            i2 += 1
    while i1<len(l1):
        print_local(l1[i1],'removed')
        i1 += 1
    while i2<len(l2):
        print_local(l2[i2],'added')
        i2 += 1
    # compare subfolders recursively
    for sd1,sd2 in common_dirs:
        compare_dirs(sd1, sd2)

if __name__=="__main__":
    compare_dirs(sys.argv[1], sys.argv[2])
Run Code Online (Sandbox Code Playgroud)

样品用法:

user@laptop:~$ python3 compare_dirs.py dir1/ dir2/
DIR  dir1/out/flavor-domino removed
DIR  dir2/out/flavor-maxim2 added
DIR  dir1/target/vendor/flavor-domino removed
DIR  dir2/target/vendor/flavor-maxim2 added
FILE dir1/tmp/.kconfig-flavor_domino removed
FILE dir2/tmp/.kconfig-flavor_maxim2 added
DIR  dir2/tools/tools/LiveSuit_For_Linux64 added
Run Code Online (Sandbox Code Playgroud)

或者,如果您只想查看第一个目录中的文件:

user@laptop:~$ python3 compare_dirs.py dir2/ dir1/ | grep dir1
DIR  dir1/out/flavor-domino added
DIR  dir1/target/vendor/flavor-domino added
FILE dir1/tmp/.kconfig-flavor_domino added
Run Code Online (Sandbox Code Playgroud)

PS如果你需要比较文件大小和文件哈希值以进行潜在的更改,我在这里发布了一个更新的脚本:https://gist.github.com/amakukha/f489cbde2afd32817f8e866cf4abe779


jal*_*tek 6

另一个(大型目录可能更快)方法:

$ find dir1 | sed 's,^[^/]*/,,' | sort > dir1.txt && find dir2 | sed 's,^[^/]*/,,' | sort > dir2.txt
$ diff dir1.txt dir2.txt
Run Code Online (Sandbox Code Playgroud)

由于Erik的帖子,sed命令删除了第一个目录组件)


小智 5

这有点晚了,但可能会对某人有所帮助。不知道diff或rsync是否仅以这种裸格式吐出文件名。感谢plhn提供了很好的解决方案,我在下面进行了扩展。

如果只需要文件名,那么以干净的格式复制所需的文件很容易,则可以使用find命令。

comm -23 <(find dir1 | sed 's/dir1/\//'| sort) <(find dir2 | sed 's/dir2/\//'| sort) | sed 's/^\//dir1/'
Run Code Online (Sandbox Code Playgroud)

假定dir1和dir2都在同一父文件夹中。sed只是删除了父文件夹,因此您可以将苹果与苹果进行比较。最后一个sed仅将dir1名称放回去。

如果只需要文件:

comm -23 <(find dir1 -type f | sed 's/dir1/\//'| sort) <(find dir2 -type f | sed 's/dir2/\//'| sort) | sed 's/^\//dir1/'
Run Code Online (Sandbox Code Playgroud)

对于目录类似:

comm -23 <(find dir1 -type d | sed 's/dir1/\//'| sort) <(find dir2 -type d | sed 's/dir2/\//'| sort) | sed 's/^\//dir1/'
Run Code Online (Sandbox Code Playgroud)


Ari*_*ris 5

接受的答案还将列出两个目录中都存在但内容不同的文件。要仅列出dir1中存在的文件,可以使用:

diff -r dir1 dir2 | grep 'Only in' | grep dir1 | awk '{print $4}' > difference1.txt
Run Code Online (Sandbox Code Playgroud)

说明:

  • diff -r dir1 dir2:比较
  • grep“仅在”:获取包含“仅在”的行
  • grep dir1:获取包含dir的行


Mik*_*inn 5

此答案通过添加-D选项来优化@ Adail-Junior的建议之一,这在两个比较目录都不是git存储库的情况下很有用:

git diff -D --no-index dir1/ dir2/
Run Code Online (Sandbox Code Playgroud)

如果您使用,-D则不会看到与的比较/dev/nulltext Binary files a/whatever and /dev/null differ