仅比较文件/文件夹名称上的目录,打印任何差异?

Ben*_*ron 2 python comparison directory-structure python-3.3

如何递归比较两个目录(比较应仅基于文件名)并仅在一个或另一个目录中打印文件/文件夹?

我正在使用Python 3.3.

我见过这个filecmp模块,然而,它似乎并没有完全符合我的需要.最重要的是,它不仅仅基于文件名来比较文件.

这是我到目前为止所得到的:

import filecmp
dcmp = filecmp.dircmp('./dir1', './dir2')
dcmp.report_full_closure()
Run Code Online (Sandbox Code Playgroud)

dir1 看起来像这样:

dir1
  - atextfile.txt
  - anotherfile.xml
  - afolder
    - testscript.py
  - anotherfolder
    - file.txt
  - athirdfolder
Run Code Online (Sandbox Code Playgroud)

而且dir2看起来是这样的:

dir2
  - atextfile.txt
  - afolder
    - testscript.py
  - anotherfolder
    - file.txt
    - file2.txt
Run Code Online (Sandbox Code Playgroud)

我希望结果看起来像:

files/folders only in dir1
  * anotherfile.xml
  * athirdfolder

files/folders only in dir2
  * anotherfolder/file2.txt
Run Code Online (Sandbox Code Playgroud)

我需要一种简单的pythonic方法来比较两个仅基于文件/文件夹名称的指令,并打印出差异.

另外,我需要一种方法来检查目录是否相同.

注意:我已经在stackoverflow和google上搜索了类似的内容.我看到很多关于如何比较考虑文件内容的文件的例子,但我找不到任何关于文件名的内容.

Hai*_* Vu 6

我的解决方案使用set()类型来存储相对路径.然后比较只是集合减法的问题.

import os
import re

def build_files_set(rootdir):
    root_to_subtract = re.compile(r'^.*?' + rootdir + r'[\\/]{0,1}')

    files_set = set()
    for (dirpath, dirnames, filenames) in os.walk(rootdir):
        for filename in filenames + dirnames:
            full_path = os.path.join(dirpath, filename)
            relative_path = root_to_subtract.sub('', full_path, count=1)
            files_set.add(relative_path)

    return files_set

def compare_directories(dir1, dir2):
    files_set1 = build_files_set(dir1)
    files_set2 = build_files_set(dir2)
    return (files_set1 - files_set2, files_set2 - files_set1)

if __name__ == '__main__':
    dir1 = 'old'
    dir2 = 'new'
    in_dir1, in_dir2 = compare_directories(dir1, dir2)

    print '\nFiles only in {}:'.format(dir1)
    for relative_path in in_dir1:
        print '* {0}'.format(relative_path)

    print '\nFiles only in {}:'.format(dir2)
    for relative_path in in_dir2:
        print '* {0}'.format(relative_path)
Run Code Online (Sandbox Code Playgroud)

讨论

  • 主力是函数build_files_set().它遍历一个目录并创建一组相对文件/目录名称

  • 函数compare_directories()接受两组文件并返回差异 - 非常直接.