2013-08-23 17 views
48

メインフォルダー内のサブフォルダーを再帰的に調べ、特定のファイルタイプのリストを作成するスクリプトを作成しています。私はこのスクリプトに問題があります。リスト内の再帰的サブフォルダの検索とリターンファイルpython

for root, subFolder, files in os.walk(PATH): 
    for item in files: 
     if item.endswith(".txt") : 
      fileNamePath = str(os.path.join(root,subFolder,item)) 

を次のようにその現在設定されている問題は、サブフォルダの変数は、サブフォルダのリストではなく、ITEMファイルがあるフォルダに引っ張っているということです。私は前にサブフォルダのためのforループを実行していることを考えて、パスの最初の部分を結合するが、私は誰もがその前に何か提案を持っているかどうかを確認するためにIdをダブルチェックを考え出しました。ご協力いただきありがとうございます!

答えて

83

rootと呼ばれるdirpathを使用してください。あなたに再帰するos.walkをたくないフォルダがある場合は、それをプルーニングすることができますので、dirnamesが供給されています。

import os 
result = [os.path.join(dp, f) for dp, dn, filenames in os.walk(PATH) for f in filenames if os.path.splitext(f)[1] == '.txt'] 

編集:

最新downvoteした後、globは拡張子で選択するための優れたツールであることを私に起こりました。

import os 
from glob import glob 
result = [y for x in os.walk(PATH) for y in glob(os.path.join(x[0], '*.txt'))] 

はまた、発電機のバージョン

from itertools import chain 
result = (chain.from_iterable(glob(os.path.join(x[0], '*.txt')) for x in os.walk('.'))) 
+0

それはリスト内包しなかった場合、これははるかに読みやすいだろう... –

19

Changed in Python 3.5: Support for recursive globs using “**”.

glob.glob()は新しいrecursive parameterを得ました。

あなたは(再帰的にサブディレクトリを含む)my_path下にあるすべての.txtファイルを取得したい場合は:あなたは、代替としてiglobを使用することができますイテレータが必要な場合は

import glob 

files = glob.glob(my_path + '/**/*.txt', recursive=True) 

# my_path/  the dir 
# **/  every file and dir under my_path 
# *.txt  every file that ends with '.txt' 

を:

for file in glob.iglob(my_path, recursive=False): 
    # ... 
+1

はTypeError:グロブ()「再帰的な」予期しないキーワード引数 – CyberJacob

+0

それは作業する必要があるのです。 3.5以上のバージョンを使用していることを確認してください。詳細については、私の答えにドキュメントへのリンクを追加しました。 – Rotareti

+0

それはなぜでしょう、私は2.7 – CyberJacob

2

そのありませんほとんどのpythonic答えが、再帰のきちんとしたレッスンであるので、私はここでそれを置くでしょう

def find_files(files, dirs=[], extensions=[]): 
    new_dirs = [] 
    for d in dirs: 
     try: 
      new_dirs += [ os.path.join(d, f) for f in os.listdir(d) ] 
     except OSError: 
      if os.path.splitext(d)[1] in extensions: 
       files.append(d) 

    if new_dirs: 
     find_files(files, new_dirs, extensions) 
    else: 
     return 
私のマシン上で

は、私は2つのフォルダ、rootroot2

[email protected] ]ls -R root root2 
root: 
temp1 temp2 

root/temp1: 
temp1.1 temp1.2 

root/temp1/temp1.1: 
f1.mid 

root/temp1/temp1.2: 
f.mi f.mid 

root/temp2: 
tmp.mid 

root2: 
dummie.txt temp3 

root2/temp3: 
song.mid 

を持って、私はちょうど行うことができ、私はこれらのディレクトリのいずれかですべて.txtとすべての.midファイルを見つけたいとしましょう

files = [] 
find_files(files, dirs=['root','root2'], extensions=['.mid','.txt']) 
print(files) 

#['root2/dummie.txt', 
# 'root/temp2/tmp.mid', 
# 'root2/temp3/song.mid', 
# 'root/temp1/temp1.1/f1.mid', 
# 'root/temp1/temp1.2/f.mid'] 
関連する問題