2013-07-09 2 views
2

J'ai deux dossiers, dir1 et dir2. Je dois trouver les fichiers qui sont dans le dossier (ou dans le sous-dossier) avec le même nom mais un contenu différent.Python - Fichier avec le même nom mais un contenu différent

quelque chose comme: so.1.0/p/q/search.c so.1.1/p/q/search.c diffèrent

Toutes les idées?

obtenir des fichiers i besoin de cette façon:

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)) 

maintenant je voudrais comparer les deux listes de fichiers, obtenir les entrées qui ont le même nom et vérifier si elles sont différentes pour le contenu. Qu'est-ce que tu penses?

+0

[qu'avez-vous essayé] (http://mattgemmell.com/2008/12/08/what-have-you-tried/)? – stalk

Répondre

1

Comme @Martijn a répondu à traverser fin, vous pouvez utiliser os.walk()

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

Et pour la comparaison des noms de fichiers que je recommande filecmp

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

Et pour comparant le fil e vérification de contenu difflib

2

Utilisez os.walk() pour générer une liste de fichiers dans les deux répertoires (avec des chemins par rapport à leurs racines):

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) 

Créer un ensemble de chemins d'un:

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)) 

puis trouver toutes les noms de chemin dans l'autre racine qui sont les mêmes en utilisant une intersection définie:

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() boucle sur les fichiers pour jumeler efficacement les lignes; Si un fichier est plus long que l'autre, les lignes restantes seront appariées avec None pour vous assurer que vous en détectez une différente de l'autre.

Démo:

$ 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

trop vite :) Nice –

Questions connexes