特定のディレクトリ内のすべてのディレクトリ、サブディレクトリ、およびファイルを一覧表示するスクリプトを作成しようとしています。
これを試しました:
import sys,os
root = "/home/patate/directory/"
path = os.path.join(root, "targetdirectory")
for r,d,f in os.walk(path):
for file in f:
print os.path.join(root,file)
残念ながら適切に動作しません。
すべてのファイルを取得しますが、完全なパスは取得しません。
たとえば、dir構造体が次の場合:
/home/patate/directory/targetdirectory/123/456/789/file.txt
それは印刷されます:
/home/patate/directory/targetdirectory/file.txt
必要なのは最初の結果です。どんな助けも大歓迎です!ありがとう。
os.path.join
を使用して、ディレクトリとファイルnameを連結します。
for path, subdirs, files in os.walk(root):
for name in files:
print os.path.join(path, name)
path
の使用は正しくないため、連結ではroot
ではなくroot
の使用に注意してください。
Python 3.4では、パス操作を簡単にするために pathlib モジュールが追加されました。したがって、os.path.join
と同等のものは次のようになります。
pathlib.PurePath(path, name)
pathlib
の利点は、パスでさまざまな便利なメソッドを使用できることです。具象Path
バリアントを使用すると、ディレクトリへの変更、パスの削除、それが指すファイルのオープンなど、実際のOS呼び出しを実行することもできます。
念のため...何らかのパターン(たとえば* .py)に一致するディレクトリおよびサブディレクトリ内のすべてのファイルを取得します。
import os
from fnmatch import fnmatch
root = '/some/directory'
pattern = "*.py"
for path, subdirs, files in os.walk(root):
for name in files:
if fnmatch(name, pattern):
print os.path.join(path, name)
import os
[val for sublist in [[os.path.join(i[0], j) for j in i[2]] for i in os.walk('./')] for val in sublist]
# Meta comment to ease selecting text
最も外側のval for sublist in ...
ループは、リストを1次元にフラット化します。 j
ループは、すべてのファイルベース名のリストを収集し、それを現在のパスに結合します。最後に、i
ループは、すべてのディレクトリとサブディレクトリを反復処理します。
この例では、ハードコーディングされたパス./
を os.walk(...)
呼び出しで使用しています。任意のパス文字列を補足できます。
注: os.path.expanduser
および/または os.path.expandvars
は、~/
のようなパス文字列に使用できます
ファイルのベース名テストとディレクトリ名テストを簡単に追加できます。
たとえば、*.jpg
ファイルのテスト:
... for j in i[2] if j.endswith('.jpg')] ...
さらに、.git
ディレクトリを除外します:
... for i in os.walk('./') if '.git' not in i[0].split('/')]
'root'の代わりに 'r'を結合で使用する必要があります
コメントできなかったので、ここに答えを書いてください。これは私が見た中で最も明確な1行です。
import os
[os.path.join(path, name) for path, subdirs, files in os.walk(root) for name in files]
私が作ったこのサンプルをご覧ください。非推奨のos.path.walk関数を使用します。リストを使用してすべてのファイルパスを保存します
root = "Your root directory"
ex = ".txt"
where_to = "Wherever you wanna write your file to"
def fileWalker(ext,dirname,names):
'''
checks files in names'''
pat = "*" + ext[0]
for f in names:
if fnmatch.fnmatch(f,pat):
ext[1].append(os.path.join(dirname,f))
def writeTo(fList):
with open(where_to,"w") as f:
for di_r in fList:
f.write(di_r + "\n")
if __== '__main__':
li = []
os.path.walk(root,fileWalker,[ex,li])
writeTo(li)
少しシンプルなワンライナー:
import os
from itertools import product, chain
chain.from_iterable([["\\".join(w) for w in product([i[0]], i[2])] for i in os.walk(dir)])
ここでのすべての例はwalk
(join
を使用)のみを使用しているため、Niceの例とlistdir
との比較を示します。
import os, time
def listFiles1(root): # listdir
allFiles = []; walk = [root]
while walk:
folder = walk.pop(0)+"/"; items = os.listdir(folder) # items = folders + files
for i in items: i=folder+i; (walk if os.path.isdir(i) else allFiles).append(i)
return allFiles
def listFiles2(root): # listdir/join (takes ~1.4x as long) (and uses '\\' instead)
allFiles = []; walk = [root]
while walk:
folder = walk.pop(0); items = os.listdir(folder) # items = folders + files
for i in items: i=os.path.join(folder,i); (walk if os.path.isdir(i) else allFiles).append(i)
return allFiles
def listFiles3(root): # walk (takes ~1.5x as long)
allFiles = []
for folder, folders, files in os.walk(root):
for file in files: allFiles+=[folder.replace("\\","/")+"/"+file] # folder+"\\"+file still ~1.5x
return allFiles
def listFiles4(root): # walk/join (takes ~1.6x as long) (and uses '\\' instead)
allFiles = []
for folder, folders, files in os.walk(root):
for file in files: allFiles+=[os.path.join(folder,file)]
return allFiles
for i in range(100): files = listFiles1("src") # warm up
start = time.time()
for i in range(100): files = listFiles1("src") # listdir
print("Time taken: %.2fs"%(time.time()-start)) # 0.28s
start = time.time()
for i in range(100): files = listFiles2("src") # listdir and join
print("Time taken: %.2fs"%(time.time()-start)) # 0.38s
start = time.time()
for i in range(100): files = listFiles3("src") # walk
print("Time taken: %.2fs"%(time.time()-start)) # 0.42s
start = time.time()
for i in range(100): files = listFiles4("src") # walk and join
print("Time taken: %.2fs"%(time.time()-start)) # 0.47s
したがって、自分で確認できるように、listdir
バージョンの方がはるかに効率的です。 (そしてjoin
は遅い)