2013-07-09 6 views
2

두 개의 폴더 dir1과 dir2가 있습니다. 같은 이름이지만 다른 내용을 가진 폴더 (또는 하위 폴더)에있는 파일을 찾아야합니다. 같은Python - 같은 이름이지만 다른 내용의 파일

뭔가 : so.1.0/P/Q/search.c so.1.1/P/Q/search.c는

어떤 아이디어 차이? 그들은 콘텐츠를 다른 경우

import os, sys, fnmatch, filecmp 

folder1 = sys.argv[1] 
folder2 = sys.argv[2] 

filelist1 = [] 

filelist2 = [] 

for root, dirs, files in os.walk(folder1): 
    for filename in fnmatch.filter(files, '*.c'): 
     filelist1.append(os.path.join(root, filename)) 

for root, dirs, files, in os.walk(folder1): 
    for filename in fnmatch.filter(files, '*.h'): 
     filelist1.append(os.path.join(root, filename)) 

for root, dirs, files in os.walk(folder2): 
    for filename in fnmatch.filter(files, '*.c'): 
     filelist2.append(os.path.join(root, filename)) 

for root, dirs, files, in os.walk(folder2): 
    for filename in fnmatch.filter(files, '*.h'): 
     filelist2.append(os.path.join(root, filename)) 

지금 내가, 파일의 두 목록을 비교 같은 파일 이름을 가지고있는 항목을 얻을 확인하고 싶습니다 :

은 내가 이런 식으로 필요한 파일을 얻을. 어떻게 생각해?

+0

[무엇을 시도해 봤습니까?] (http://mattgemmell.com/2008/12/08/what-have-you-tried/)? – stalk

답변

1

당신이 사용할 수있는 os.walk()

for root, dirs, files in os.walk(path): 
    for name in files: 

그리고 파일 이름 비교를 위해 내가 filecmp

>>> import filecmp 
>>> filecmp.cmp('undoc.rst', 'undoc.rst') 
True 
>>> filecmp.cmp('undoc.rst', 'index.rst') 
False 

그리고 대한을 추천 할 것입니다 비교 필 전자 콘텐츠 체크 difflib

2

사용 os.walk() (뿌리 상대 패스) 중 하나 디렉토리에있는 파일의 목록 생성 :

import os 

def relative_files(path): 
    """Generate filenames with pathnames relative to the initial path.""" 
    for root, dirnames, files in os.walk(path): 
     relroot = os.path.relpath(root, path) 
     for filename in files: 
      yield os.path.join(relroot, filename) 

하나에서 경로의 집합을 만듭니다

root_one = 'so.1.0' # use an absolute path here 
root_two = 'so.1.1' # use an absolute path here 
files_one = set(relative_files(root_one)) 

다음 찾기를 모든 교차로를 사용하여 다른 루트의 경로 이름은 동일합니다.

from itertools import izip_longest 

def different_files(root_one, root_two): 
    """Yield files that differ between the two roots 

    Generate pathnames relative to root_one and root_two that are present in both 
    but have different contents. 

    """ 
    files_one = set(relative_files(root_one)) 
    for same in files_one.intersection(relative_files(root_two)): 
     # same is a relative path, so same file in different roots 
     with open(os.path.join(root_one, same)) as f1, open(os.path.join(root_two, same)) as f2: 
      if any(line1 != line2 for line1, line2 in izip_longest(f1, f2)): 
       # lines don't match, so files don't match! 
       yield same 

itertools.izip_longest() 파일을 효율적으로 페어링하여 루프 처리합니다. 한 파일이 다른 파일보다 길면 남은 행은 None과 쌍을 이루어 다른 파일과 다른 점을 감지합니다.

데모 : @Martijn이 목적을 가로 지르는 대한 대답으로

$ mkdir -p /tmp/so.1.0/p/q 
$ mkdir -p /tmp/so.1.1/p/q 
$ echo 'file one' > /tmp/so.1.0/p/q/search.c 
$ echo 'file two' > /tmp/so.1.1/p/q/search.c 
$ echo 'file three' > /tmp/so.1.1/p/q/ignored.c 
$ echo 'matching' > /tmp/so.1.0/p/q/same.c 
$ echo 'matching' > /tmp/so.1.1/p/q/same.c 

>>> for different in different_files('/tmp/so.1.0', '/tmp/so.1.1'): 
...  print different 
... 
p/q/search.c 
+0

너무 빠름 :) 니스 –

관련 문제