2012-11-26 161 views
31

我有一個root-ish目錄包含多個子目錄,所有這些子目錄都包含一個文件名data.txt。我想要做的是編寫一個接受「root」目錄的腳本,然後讀取所有子目錄並讀取子目錄中的每個「data.txt」,然後將每個data.txt文件中的內容寫入一個輸出文件。如何遞歸遍歷所有子目錄並讀取文件?

這裏是我的代碼片段:

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

我DoSomething的()的一部分 - 我已經測試並確認它,如果我正在運行的部分只是一個文件的工作。我也證實,如果我告訴它打印文件(註釋掉的行),腳本打印出'data.txt'。

現在如果我運行它的Python給了我這個錯誤:

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

我不知道爲什麼它不能找到它 - 畢竟,它打印出的data.txt如果我取消了'打印文件'行。我做錯了什麼?

+1

只是一個時尚點評:一旦嵌套得到這個深刻的,它可以是難以閱讀。爲了簡化,我將內部部分放在一個單獨的'def do_file(filename):...'函數中。你也可以通過'if file =='data.txt':continue'來簡化並保存一個關卡。另見[PEP 20](http://www.python.org/dev/peps/pep-0020/):「Flat比嵌套更好」。 –

回答

50

你需要使用絕對路徑,你的file變量只是一個沒有目錄路徑的本地文件名。該root變量是路徑:

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

完美運作。謝謝! – Joe

+7

如果像我一樣閱讀此文件的人想要額外過濾被迭代的文件名,這個問題的答案證明是非常有用的:http://stackoverflow.com/questions/2186525/use-a-glob-to-find-files在python – BigglesZX

+2

['os.walk()'+遵循符號鏈接](http://stackoverflow.com/questions/3771696/python-os-walk-follow-symlinks)地址如何有這個後續鏈接。 – Schorsch

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

的功能的方法來獲得樹看起來更短,更清潔,更Python。

您可以包裝os.path.join(dirpath, filename)到任何函數來處理你的文件或保存路徑的陣列進行進一步的處理

相關問題