比较目录但不比较文件内容


21

使用diff -r我可以执行此任务,但是它花费了很长时间,因为diff检查文件的内容。

我想要确定两个文件的大小,上次修改的文件等相同的内容。但是却无法一点一点地检查文件(例如,视频需要很长时间)

还有其他办法吗?

Answers:


20

默认情况下,rsync仅比较文件元数据。

rsync -n -a -i --delete source/ target/

说明:

  • -n 实际不复制或删除<-这很重要!! 1
  • -a 比较文件的所有元数据,例如时间戳和属性
  • -i 每个文件打印一行信息
  • --delete 还报告不在源中的文件

注意:必须在目录名称后加上斜杠。这是一个rsync的事情。

如果您还想查看为相同文件打印的行,请提供-i两次

rsync -n -a -ii --delete source/ target/

示例输出:

*deleting   removedfile   (file in target but not in source)
.d..t...... ./            (directory with different timestamp)
>f.st...... modifiedfile  (file with different size and timestamp)
>f+++++++++ newfile       (file in source but not in target)
.f          samefile      (file that has same metadata. only with -ii)

请记住,rsync仅比较元数据。这意味着如果文件内容已更改但元数据保持不变,则rsync将报告该文件相同。这是不可能的情况。因此,要么相信当元数据相同时数据就相同,要么必须逐位比较文件数据。

红利:有关进度信息,请参见此处:估计完成rsync所需的时间或工作?


1
斜线source/target/都非常重要!(如果没有它们,您将比较源目录名称和目标目录名称以及子目录文件名,因此所有文件名都会有所不同。)
peschü

希望我早已读过您的评论,这是如此重要!我只省略了源代码中的斜线,然后我想知道为什么目标中的文件没有显示为*deleting,而是仅显示了源中的文件。斜线很容易被意外忘记,然后您会得到一个合理但错误的输出。
user643011

3

-q--brief)选项与diff -rdiff -qr)一起使用。从infoGNU页面diff

1.6总结哪些文件不同

当您只想查找文件是否不同,而又不关心差异时,可以使用摘要输出格式。在这种格式下,-- diff' simply reports whether files differ. Thebrief'(`-q')选项不显示文件之间的差异,而是选择此输出格式。

比较两个目录的内容时,此格式特别有用。它也比常规的逐行比较要快得多,因为`diff'可以在知道存在差异后立即停止分析文件。

这不会逐行比较,而是整个文件,这大大加快了处理器的速度(您要查找的内容)。


1
-q的问题是它比较正常,并且发现差异时停止(如果是正常模式,它将继续比较),因此,如果大文件相同,它将持续很多时间。
eez0 2012年

2

这是一个快速的python脚本,它将检查文件名,mtimes和文件大小是否相同:

import os
import sys

def getStats(path):
    for pathname, dirnames, filenames in os.walk(path):
        for filename in ( os.path.join(pathname, x) for x in filenames ):
            stat = os.stat(filename)
            yield filename[len(path):], stat.st_mtime, stat.st_size

sys.exit(tuple(getStats(sys.argv[1])) != tuple(getStats(sys.argv[2])))

1

如果您只需要知道两个文件系统分支中的文件是否不同(无需查看文件内部),则可以执行以下操作:

find /opt/branch1 -type f | sort | xargs -i md5sum {} >/tmp/branch1;
find /opt/branch2 -type f | sort | xargs -i md5sum {} >/tmp/branch2;
diff /tmp/branch1 /tmp/branch2;

高温超导


0

基于Chris Down的脚本,此脚本更具“视觉效果”。使用两个参数folder1和调用它folder2,它将遍历第一个文件夹,并为每个文件在第二个文件夹中搜索对应的文件。如果找到,则相对路径以绿色打印,如果它们的修改时间或大小不同,则以黄色打印,如果找不到,则以红色打印。

#!/usr/bin/env python

import os
import sys
from termcolor import colored

def compare_filestats(file1,file2):
    """
    Compares modified time and size between two files.
    Return:
        -1 if file1 or file2 does not exist
         0 if they exist and compare equal
         1 if they have different modified time, but same size
         2 if they have different size, but same modified time
         3 if they have different size, and different modified time
    """

    if not os.path.exists(file1) or not os.path.exists(file2):
        return -1

    stat1 = os.stat(file1)
    stat2 = os.stat(file2)

    return (stat1.st_mtime != stat2.st_mtime) \
        + 2*(stat1.st_size != stat2.st_size)

def compare_folders(folder1,folder2):
    """
    folder1: serves as reference and will be walked through
    folder2: serves as target and will be querried for each file in folder1

    Prints colored status for each file in folder1:
        missing: file was not found in folder2 
        mtime  : modified time is different
        size   : filesize is different
        ok     : found with same filestats
    """
    for dirpath, dirnames, filenames in os.walk(folder1):
        for file1 in ( os.path.join(dirpath, x) for x in filenames ):
            relpath = file1[len(folder1):]
            file2 = os.path.join( folder2, relpath )
            comp = compare_filestats(file1,file2)

            if comp < 0:
                status = colored('[missing]','red')
            elif comp == 1:
                status = colored('[mtime  ]','yellow')
            elif comp >= 2:
                status = colored('[size   ]','yellow')
            else:
                status = colored('[ok     ]','green')

            print status, relpath

if __name__ == '__main__':
    compare_folders(sys.argv[1],sys.argv[2])

请注意,这不足以确定两个文件夹是否相同,您需要同时运行这两种方法来确保。在实践中,如果您只是想知道文件夹是否相同,那么克里斯的脚本会更好。如果你想知道一个文件夹与另一个文件夹之间缺少什么或不同之处,那么我的脚本会告诉您。

注意:您将需要安装termcolor pip install termcolor


0

如果您只想比较结构和有关文件的一些基本信息,则可以尝试如下操作:

diff <(cd $DIR1 && ls -laR) <(cd $DIR2 && ls -laR)

我没有测试它,所以欢迎任何编辑:)


2
这将不起作用,因为目录名称本身也将出现在结果中。
克里斯·唐纳

如果我们要排除具有目录名称的第一列怎么办?像<(ls -laR | awk'{$ 1 =“”; print}')
Volodymyr

并非所有行都是目录名,因此无法正常工作。
克里斯·

利用每个人<()都有自己的环境这一事实。编辑。
CVn
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.