ルートっぽいディレクトリに複数のサブディレクトリがあり、そのすべてに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()の部分 -- 1つのファイルに対してその部分を実行する場合、動作することをテストし確認しました。また、ファイルを出力するように指示すると(コメントアウトした行)、 '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'
結局、 'print file' 行のコメントを解除すると data.txt が出力されます。私は何を間違えているのでしょうか?
絶対パスを使用する必要があります。変数 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()
[os.path.join(dirpath, filename) for dirpath, dirnames, filenames in os.walk(rootdir)
for filename in filenames]
関数的なアプローチでツリーを取得すると、より短く、よりきれいに、よりPythonicに見えます。
o.path.join(dirpath, filename)`を任意の関数にラップして、取得したファイルを処理したり、パスの配列を保存して次の処理に利用することができます。