これは私が持っているものです:
glob(os.path.join('src','*.c'))
しかし、私はsrcのサブフォルダを検索したいのです。このような何かがうまくいくでしょう:
glob(os.path.join('src','*.c'))
glob(os.path.join('src','*','*.c'))
glob(os.path.join('src','*','*','*.c'))
glob(os.path.join('src','*','*','*','*.c'))
しかし、これは明らかに限られていて不格好です。
Python 3.5+
新しいPythonを使っているので、 pathlib
モジュールの pathlib.Path.glob
を使うべきです。
from pathlib import Path
for filename in Path('src').glob('**/*.c'):
print(filename)
Pathlibを使用したくない場合は、 glob.glob
を使用してください。ただし、recursive
キーワードパラメータを忘れずに渡してください。
一致するファイルがドット(。)で始まる場合。カレントディレクトリのファイルやUnixベースのシステムの隠しファイルのように、以下の os.walk
ソリューションを使用してください。
古いPythonのバージョン
古いPythonバージョンでは、 os.walk
を使用してディレクトリを再帰的に検索し、 fnmatch.filter
を使用して単純な式と照合します。
import fnmatch
import os
matches = []
for root, dirnames, filenames in os.walk('src'):
for filename in fnmatch.filter(filenames, '*.c'):
matches.append(os.path.join(root, filename))
他のソリューションと似ていますが、os.walkはすでにファイル名をリストしているので、globの代わりにfnmatch.fnmatchを使用します。
import os, fnmatch
def find_files(directory, pattern):
for root, dirs, files in os.walk(directory):
for basename in files:
if fnmatch.fnmatch(basename, pattern):
filename = os.path.join(root, basename)
yield filename
for filename in find_files('src', '*.c'):
print 'Found C source:', filename
また、ジェネレータを使用すると、すべてのファイルを見つけてからそれらを処理するのではなく、見つかったとおりに各ファイルを処理できます。
Globモジュールを再帰的globbingの**をサポートするように修正しました。
>>> import glob2
>>> all_header_files = glob2.glob('src/**/*.c')
https://github.com/miracle2k/python-glob2/ /
ユーザに**構文を使用する機能を提供したい場合、つまりos.walk()だけでは十分ではない場合に役立ちます。
import os
import fnmatch
def recursive_glob(treeroot, pattern):
results = []
for base, dirs, files in os.walk(treeroot):
goodfiles = fnmatch.filter(files, pattern)
results.extend(os.path.join(base, f) for f in goodfiles)
return results
fnmatch
は glob
とまったく同じパターンを与えるので、これは非常に近い意味でglob.glob
の本当に素晴らしい置き換えです。 glob.iglob
の代わりになる繰り返しバージョン(ジェネレータなど)は、簡単な適応です(最後に返される1つの結果リストをyield
する代わりに、単に中間結果をextend
にする)。
あなたの基準に合うファイル名を集めるのにos.walk
を使いたいでしょう。例えば:
import os
cfiles = []
for root, dirs, files in os.walk('src'):
for file in files:
if file.endswith('.c'):
cfiles.append(os.path.join(root, file))
これは、ネストされたリスト内包表記、glob
の代わりにos.walk
、および単純なサフィックスマッチングを使用した解決策です。
import os
cfiles = [os.path.join(root, filename)
for root, dirnames, filenames in os.walk('src')
for filename in filenames if filename.endswith('.c')]
それはワンライナーに圧縮することができます:
import os;cfiles=[os.path.join(r,f) for r,d,fs in os.walk('src') for f in fs if f.endswith('.c')]
または関数として一般化
import os
def recursive_glob(rootdir='.', suffix=''):
return [os.path.join(looproot, filename)
for looproot, _, filenames in os.walk(rootdir)
for filename in filenames if filename.endswith(suffix)]
cfiles = recursive_glob('src', '.c')
完全なglob
スタイルのパターンが必要な場合は、AlexとBrunoの例に従って、fnmatch
を使用してください。
import fnmatch
import os
def recursive_glob(rootdir='.', pattern='*'):
return [os.path.join(looproot, filename)
for looproot, _, filenames in os.walk(rootdir)
for filename in filenames
if fnmatch.fnmatch(filename, pattern)]
cfiles = recursive_glob('src', '*.c')
最近私は拡張子.jpgを付けて写真を復元しなければなりませんでした。 Photcを実行して、膨大な種類の拡張子を持つ、2209個のファイルを含む4579個のディレクトリを復元しました。
#!/usr/binenv python2.7
import glob
import shutil
import os
src_dir = "/home/mustafa/Masaüstü/yedek"
dst_dir = "/home/mustafa/Genel/media"
for mediafile in glob.iglob(os.path.join(src_dir, "*", "*.jpg")): #"*" is for subdirectory
shutil.copy(mediafile, dst_dir)
JohanとBrunoは、述べられているように、最低限の要件について優れたソリューションを提供しています。私は、このようなより複雑なシナリオを扱うことができるAnt FileSet and Globs を実装する Formic をリリースしました。あなたの要件の実装は以下のとおりです。
import formic
fileset = formic.FileSet(include="/src/**/*.c")
for file_name in fileset.qualified_files():
print file_name
他の答えに基づいて、これは私の現在の実用的な実装で、これはルートディレクトリのネストされたxmlファイルを取得します。
files = []
for root, dirnames, filenames in os.walk(myDir):
files.extend(glob.glob(root + "/*.xml"))
私は本当にPythonを楽しんでいます:)
Globモジュールだけを使ってそれを行う別の方法です。 rglobメソッドに開始ベースディレクトリと一致するパターンをシードするだけで、一致するファイル名のリストが返されます。
import glob
import os
def _getDirs(base):
return [x for x in glob.iglob(os.path.join( base, '*')) if os.path.isdir(x) ]
def rglob(base, pattern):
list = []
list.extend(glob.glob(os.path.join(base,pattern)))
dirs = _getDirs(base)
if len(dirs):
for d in dirs:
list.extend(rglob(os.path.join(base,d), pattern))
return list
それはfnmatchか正規表現を使います:
import fnmatch, os
def filepaths(directory, pattern):
for root, dirs, files in os.walk(directory):
for basename in files:
try:
matched = pattern.match(basename)
except AttributeError:
matched = fnmatch.fnmatch(basename, pattern)
if matched:
yield os.path.join(root, basename)
# usage
if __== '__main__':
from pprint import pprint as pp
import re
path = r'/Users/hipertracker/app/myapp'
pp([x for x in filepaths(path, re.compile(r'.*\.py$'))])
pp([x for x in filepaths(path, '*.py')])
提案された答えに加えて、あなたはいくつかの怠惰な世代とリスト内包表記の魔法でこれをすることができます:
import os, glob, itertools
results = itertools.chain.from_iterable(glob.iglob(os.path.join(root,'*.c'))
for root, dirs, files in os.walk('src'))
for f in results: print(f)
1行に収まり、メモリ内の不要なリストを避けることに加えて、これにはNice副作用があります。**演算子と同じように使用できます。たとえば、すべてを取得するにはos.path.join(root, 'some/path/*.c')
を使用できます。この構造を持つsrcのすべてのサブディレクトリにある.cファイル。
これを作成しました..それは階層的な方法でファイルとディレクトリを印刷します
しかし私はfnmatchやwalkを使っていません
#!/usr/bin/python
import os,glob,sys
def dirlist(path, c = 1):
for i in glob.glob(os.path.join(path, "*")):
if os.path.isfile(i):
filepath, filename = os.path.split(i)
print '----' *c + filename
Elif os.path.isdir(i):
dirname = os.path.basename(i)
print '----' *c + dirname
c+=1
dirlist(i,c)
c-=1
path = os.path.normpath(sys.argv[1])
print(os.path.basename(path))
dirlist(path)
pathlib.rglob()
を考えてください。
これは、与えられた相対パターンの前に
"**/"
を追加してPath.glob()
を呼び出すのと同じです。
import pathlib
for p in pathlib.Path("src").rglob("*.c"):
print(p)
これはリスト内包表記を使ってディレクトリとすべてのサブディレクトリで multiple file extensions recursively を検索する方法です。
import os, glob
def _globrec(path, *exts):
""" Glob recursively a directory and all subdirectories for multiple file extensions
Note: Glob is case-insensitive, i. e. for '\*.jpg' you will get files ending
with .jpg and .JPG
Parameters
----------
path : str
A directory name
exts : Tuple
File extensions to glob for
Returns
-------
files : list
list of files matching extensions in exts in path and subfolders
"""
dirs = [a[0] for a in os.walk(path)]
f_filter = [d+e for d in dirs for e in exts]
return [f for files in [glob.iglob(files) for files in f_filter] for f in files]
my_pictures = _globrec(r'C:\Temp', '\*.jpg','\*.bmp','\*.png','\*.gif')
for f in my_pictures:
print f
fnmatch を除いたJohan Dahlinの答えの簡略版。
import os
matches = []
for root, dirnames, filenames in os.walk('src'):
matches += [os.path.join(root, f) for f in filenames if f[-2:] == '.c']
あるいはリスト内包表記では:
>>> base = r"c:\User\xtofl"
>>> binfiles = [ os.path.join(base,f)
for base, _, files in os.walk(root)
for f in files if f.endswith(".jpg") ]
これは、ベースファイル名だけでなく、フルパスに対してパターンを一致させる解決策です。
fnmatch.translate
を使用してglobスタイルのパターンを正規表現に変換します。この正規表現は、ディレクトリをたどっている間に見つかった各ファイルのフルパスと照合されます。
re.IGNORECASE
はオプションですが、ファイルシステム自体では大文字と小文字が区別されないため、Windowsでは望ましいです。 (私は正規表現をコンパイルするのに面倒なことはしませんでした。ドキュメントは内部的にキャッシュされるべきだと書いているからです。)
import fnmatch
import os
import re
def findfiles(dir, pattern):
patternregex = fnmatch.translate(pattern)
for root, dirs, files in os.walk(dir):
for basename in files:
filename = os.path.join(root, basename)
if re.search(patternregex, filename, re.IGNORECASE):
yield filename
python 3.5以降の場合
file_names_array = glob.glob('src/*.c', recursive=True)
編集:@NeStackのガイドに従って上記がうまくいかない場合は、試してください
file_names_array = glob.glob('src/**.c', recursive=True)
さらにあなたが必要かもしれません
for full_path_in_src in file_names_array:
print (full_path_in_src ) # be like 'abc/xyz.c'
#Full system path of this would be like => 'path till src/abc/xyz.c'
import sys, os, glob
dir_list = ["c:\\books\\heap"]
while len(dir_list) > 0:
cur_dir = dir_list[0]
del dir_list[0]
list_of_files = glob.glob(cur_dir+'\\*')
for book in list_of_files:
if os.path.isfile(book):
print(book)
else:
dir_list.append(book)
私はこの投稿の一番上の答えを修正しました..そして最近、与えられたディレクトリ(searchdir)とその下のサブディレクトリの中のすべてのファイルをループするスクリプトを作成しました。サイズ。
これが誰かに役立つことを願っています...そして彼らはディレクトリを歩いてfileinfoを取得することができます。
import time
import fnmatch
import os
def fileinfo(file):
filename = os.path.basename(file)
rootdir = os.path.dirname(file)
lastmod = time.ctime(os.path.getmtime(file))
creation = time.ctime(os.path.getctime(file))
filesize = os.path.getsize(file)
print "%s**\t%s\t%s\t%s\t%s" % (rootdir, filename, lastmod, creation, filesize)
searchdir = r'D:\Your\Directory\Root'
matches = []
for root, dirnames, filenames in os.walk(searchdir):
## for filename in fnmatch.filter(filenames, '*.c'):
for filename in filenames:
## matches.append(os.path.join(root, filename))
##print matches
fileinfo(os.path.join(root, filename))
私は python 2.x のための解決策を必要としていました 速い 大きなディレクトリで/。
私はこれを思いつきました:
import subprocess
foundfiles= subprocess.check_output("ls src/*.c src/**/*.c", Shell=True)
for foundfile in foundfiles.splitlines():
print foundfile
ls
が一致するファイルを見つけられない場合には、何らかの例外処理が必要になるかもしれないことに注意してください。