首页 文章

Linux中两个目录的区别[关闭]

提问于
浏览
233

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

diff -q dir1 dir2

上面命令的问题是,它找到了 dir1 中的文件但 dir2 中的文件以及 dir2 中的文件但 dir1 中没有,

我试图找到 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

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

15 回答

  • 5
    diff -r dir1 dir2 | grep dir1 | awk '{print $4}' > difference1.txt
    

    Explanation:

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

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

    • awk 仅打印文件名 .

  • 45

    这应该做的工作:

    diff -rq dir1 dir2
    

    解释选项(通过diff(1)man page):

    • -r - 递归比较找到的所有子目录 .

    • -q - 仅输出文件是否不同 .

  • 0
    comm -23 <(ls dir1 |sort) <(ls dir2|sort)
    

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

    关于 <( ) 标志,您可以将其谷歌为'process substitution' .

  • 4

    进行此比较的一个好方法是使用 findmd5sum ,然后使用 diff .

    例:

    使用 find 列出目录中的所有文件,然后计算每个文件的md5哈希并将其传递给文件:

    find /dir1/ -type f -exec md5sum {} \; > dir1.txt
    

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

    find /dir2/ -type f -exec md5sum {} \; > dir2.txt
    

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

    diff dir1.txt dir2.txt
    

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

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

    git diff --no-index dir1/ dir2/
    

    最好的祝福!

  • 94

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

    Meld comparing directories

  • 10

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

    vim -c "DirDiff dir1 dir2"
    

    它不仅列出了目录之间不同的文件,还允许您使用vimdiff检查/修改不同的文件 .

  • 0

    对所有回复都不满意,因为大多数回复工作得非常慢并且为大型目录产生不必要的长输出,我编写了自己的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])
    

    样品用法:

    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
    

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

    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
    

    附:如果您需要比较文件大小和文件哈希值以进行潜在更改,我在此处发布了更新的脚本:https://gist.github.com/amakukha/f489cbde2afd32817f8e866cf4abe779

  • 24

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

    $ find dir1 | sed 's,^[^/]*/,,' | sort > dir1.txt && find dir2 | sed 's,^[^/]*/,,' | sort > dir2.txt
    $ diff dir1.txt dir2.txt
    

    sed 命令删除第一个目录组件thanks to Erik`s post

  • 7

    这有点晚了但可能对某人有帮助 . 不确定diff或rsync是否只是以这样的裸格式吐出文件名 . 感谢plhn提供了我在下面展开的优秀解决方案 .

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

    comm -23 <(find dir1 | sed 's/dir1/\//'| sort) <(find dir2 | sed 's/dir2/\//'| sort) | sed 's/^\//dir1/'
    

    这假设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/'
    

    同样对于目录:

    comm -23 <(find dir1 -type d | sed 's/dir1/\//'| sort) <(find dir2 -type d | sed 's/dir2/\//'| sort) | sed 's/^\//dir1/'
    
  • 0

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

    diff -r dir1 dir2 | grep 'Only in' | grep dir1 | awk '{print $4}' > difference1.txt
    

    说明:

    • diff -r dir1 dir2:比较

    • grep 'Only in':获取包含'Only in'的行

    • grep dir1:获取包含dir的行

  • 0

    使用DIFF命令比较2个目录的简化方法

    diff filename.1 filename.2> filename.dat >>输入

    运行完成后打开filename.dat

    您将看到:仅在filename.1:filename.2仅在:directory_name:name_of_file1仅在:directory_Name:name_of_file2

  • 331

    GNU grep 可以使用选项 -v 反转搜索 . 这使 grep 报告了不匹配的行 . 通过此,您可以从 dir1 中的文件列表中删除 dir2 中的文件 .

    grep -v -F -x -f <(find dir2 -type f -printf '%P\n') <(find dir1 -type f -printf '%P\n')
    

    选项 -F -x 告诉 grep 在整行执行字符串搜索 .

  • 0

    这是用于打印同步两个目录的命令的bash脚本

    dir1=/tmp/path_to_dir1
    dir2=/tmp/path_to_dir2
    diff -rq $dir1 $dir2 | sed -e "s|Only in $dir2\(.*\): \(.*\)|cp -r $dir2\1/\2 $dir1\1|" |  sed -e "s|Only in $dir1\(.*\): \(.*\)|cp -r $dir1\1/\2 $dir2\1|"
    
  • 4

    这个答案通过添加 -D 选项优化了@Adail-Junior的一个建议,当所比较的目录都不是git存储库时,这是有用的:

    git diff -D --no-index dir1/ dir2/
    

    如果您使用 -D ,那么您将看不到与 /dev/null 的比较: text Binary files a/whatever and /dev/null differ

  • 10

    kdiff3有一个很好的文件和差异的界面目录 .

    它适用于Windows,Linux和macOS .

    您可以通过多种方式安装它:

相关问题