2012-11-26 10 views
31

Mam katalog root-ish zawierający wiele podkatalogów, z których wszystkie zawierają nazwę pliku data.txt. Chciałbym napisać skrypt, który pobiera katalog "root", a następnie odczytuje wszystkie podkatalogi i odczytuje wszystkie "dane.txt" w podkatalogach, a następnie zapisuje dane z każdego pliku data.txt do plik wyjściowy.Jak rekursywnie przeglądać wszystkie podkatalogi i czytać pliki?

Oto fragment mojego kodu:

import os 
import sys 
rootdir = sys.argv[1] 

with open('output.txt','w') as fout: 
    for root, subFolders, files in os.walk(rootdir): 
     for file in files: 
      if (file == 'data.txt'): 
       #print file 
       with open(file,'r') as fin: 
        for lines in fin: 
         dosomething() 

Moja doSomething() część - Przetestowałem i potwierdzone na to, aby działać, jeśli używam tę część tylko dla jednego pliku. Potwierdziłem również, że jeśli polecę wydrukować plik (skomentowana linia), skrypt wypisze 'data.txt'.

Teraz jeśli go uruchomić Python daje mi ten błąd:

File "recursive.py", line 11, in <module> 
    with open(file,'r') as fin: 
IOError: [Errno 2] No such file or directory: 'data.txt' 

Nie jestem pewien, dlaczego nie można go znaleźć - po wszystkim, to wypisuje dane.txt gdybym odkomentować wiersz "drukuj plik". Co robię nieprawidłowo?

+1

Wystarczy komentarz w stylu: raz gniazdowania dostaje to głęboko, może to być trudne do odczytania. Aby uprościć, umieściłbym wewnętrzną część w oddzielnej funkcji 'def do_file (filename): ...'. Możesz także wykonać 'if file == 'data.txt': continue', aby uprościć i zapisać tam poziom. Zobacz także [PEP 20] (http://www.python.org/dev/peps/pep-0020/): "Mieszkanie jest lepsze niż zagnieżdżone". –

Odpowiedz

50

Musisz użyć bezwzględnych ścieżek, twoja zmienna file jest po prostu lokalną nazwą pliku bez ścieżki katalogu. Zmienna root jest to, że ścieżka:

with open('output.txt','w') as fout: 
    for root, subFolders, files in os.walk(rootdir): 
     if 'data.txt' in files: 
      with open(os.path.join(root, 'data.txt'), 'r') as fin: 
       for lines in fin: 
        dosomething() 
+0

To działało idealnie. Dzięki! – Joe

+7

Jeśli, tak jak ja, każdy, kto to czyta, chce dodatkowo filtrować nazwy plików, które są iterowane, odpowiedź na to pytanie okazała się bardzo pomocna: http://stackoverflow.com/questions/2186525/use-a-glob-to-find-files -recursive-in-python – BigglesZX

+2

['os.walk()' + śledzenie dowiązań symbolicznych] (http://stackoverflow.com/questions/3771696/python-os-walk-follow-symlinks) opisuje, w jaki sposób należy stosować poniższe linki. – Schorsch

0
[os.path.join(dirpath, filename) for dirpath, dirnames, filenames in os.walk(rootdir) 
           for filename in filenames] 

podejście funkcjonalne, aby uzyskać jak drzewo wygląda krótszy, czystsze i bardziej pythonic.

Można owinąć os.path.join(dirpath, filename) do dowolnej funkcji do przetwarzania plików można dostać lub zapisać tablicę ścieżek do dalszego przetwarzania

Powiązane problemy