2

2つのディレクトリを再帰的に比較し(比較はファイル名のみに基づく必要があります)、一方または他方のディレクトリにのみファイル/フォルダを出力するにはどうすればよいですか?

Python3.3を使用しています。

モジュールを見たことがありfilecmpますが、必要なことを十分に行っていないようです。最も重要なことは、ファイル名だけでなく、それに基づいてファイルを比較することです。

これが私がこれまでに得たものです:

import filecmp
dcmp = filecmp.dircmp('./dir1', './dir2')
dcmp.report_full_closure()

dir1このように見えます:

dir1
  - atextfile.txt
  - anotherfile.xml
  - afolder
    - testscript.py
  - anotherfolder
    - file.txt
  - athirdfolder

そしてdir2このように見えます:

dir2
  - atextfile.txt
  - afolder
    - testscript.py
  - anotherfolder
    - file.txt
    - file2.txt

結果を次のようにしたいと思います。

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

files/folders only in dir2
  * anotherfolder/file2.txt

ファイル/フォルダー名のみに基づいて2つのディレクトリを比較し、違いを出力するための簡単なpythonic方法が必要です。

また、ディレクトリが同一かどうかを確認する方法が必要です。

注:私はstackoverflowとgoogleでこのようなものを検索しました。ファイルの内容を考慮してファイルを比較する方法の例はたくさんありますが、ファイル名だけでは何も見つかりません。

4

4 に答える 4

7

私のソリューションでは、 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)

討論

  • 主力は関数 build_files_set() です。ディレクトリを走査し、相対ファイル/ディレクトリ名のセットを作成します

  • 関数 compare_directories() は、2 つのファイル セットを受け取り、差分を返します。非常に簡単です。

于 2013-02-25T16:21:14.063 に答える
1

基本的な考え方は、os.walk メソッドを使用してファイル名の辞書を作成し、辞書を比較することです。

import os
from os.path import join
fpa = {}
for root, dirs, files in os.walk('/your/path'):
   for name in files:
   fpa[name] = 1

fpb = {}
for root, dirs, files in os.walk('/your/path2'):
   for name in files:
   fpb[name] = 1

print "files only in a"
for name in fpa.keys():
    if not(name in fpb.keys()):
        print name,"\n"

print "files only in b"
for name in fpb.keys():
    if not(name in fpa.keys()):
        print name,"\n"

私はこれをテストしなかったので、修正する必要があるかもしれません また、再利用を避けるために簡単にリファクタリングできます

于 2013-02-25T15:26:47.387 に答える