Ben*_*ner 676 python filesystems glob path fnmatch
这就是我所拥有的:
glob(os.path.join('src','*.c'))
Run Code Online (Sandbox Code Playgroud)
但我想搜索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'))
Run Code Online (Sandbox Code Playgroud)
但这显然是有限和笨重的.
Joh*_*lin 1251
Python 3.5+
从Python 3.5版开始,该pathlib.Path.rglob模块支持该pathlib指令(只有在传递glob.globflag时才会解析):
from pathlib import Path
for filename in Path('src').rglob('*.c'):
print(filename)
Run Code Online (Sandbox Code Playgroud)
如果您需要一个列表,只需使用recursive而不是os.walk.
对于匹配以点(.)开头的文件的情况; 如当前目录中的文件或基于Unix的系统上的隐藏文件,请使用os.walk下面的解决方案.
Python 2.2到3.4
对于较旧的Python版本,从Python 2.2开始,使用fnmatch.filter递归遍历目录并pathlib.Path.rglob匹配简单表达式:
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))
Run Code Online (Sandbox Code Playgroud)
Python 2.1及更早版本
对于更老的Python版本,使用pathlib针对每个文件名而不是glob.glob.
Bru*_*ira 107
与其他解决方案类似,但使用fnmatch.fnmatch而不是glob,因为os.walk已经列出了文件名:
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
Run Code Online (Sandbox Code Playgroud)
此外,使用生成器可以在找到文件时处理每个文件,而不是查找所有文件然后处理它们.
mir*_*e2k 65
我修改了glob模块以支持**用于递归globbing,例如:
>>> import glob2
>>> all_header_files = glob2.glob('src/**/*.c')
Run Code Online (Sandbox Code Playgroud)
https://github.com/miracle2k/python-glob2/
当你想为你的用户提供使用**语法的能力时很有用,因此单独的os.walk()不够好.
tal*_*nat 62
从Python 3.4开始,可以使用新路径库模块中glob()的一个Path类的方法,该模块支持通配符.例如:**
from pathlib import Path
for file_path in Path('src').glob('**/*.c'):
print(file_path) # do whatever you need with these files
Run Code Online (Sandbox Code Playgroud)
更新:
从Python 3.5开始,也支持相同的语法glob.glob().
Ale*_*lli 39
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
Run Code Online (Sandbox Code Playgroud)
fnmatch给你完全相同的模式glob,所以这是glob.glob非常接近的语义的一个很好的替代品.一个迭代版本(例如一个生成器),IOW替换glob.iglob,是一个简单的适应(只是yield你去的中间结果,而不是extend在结束时返回单个结果列表).
Geo*_*edy 20
您将要用于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))
Run Code Online (Sandbox Code Playgroud)
aka*_*ola 15
这是一个嵌套列表推导的解决方案,os.walk以及简单的后缀匹配,而不是glob:
import os
cfiles = [os.path.join(root, filename)
for root, dirnames, filenames in os.walk('src')
for filename in filenames if filename.endswith('.c')]
Run Code Online (Sandbox Code Playgroud)
它可以压缩成一行:
import os;cfiles=[os.path.join(r,f) for r,d,fs in os.walk('src') for f in fs if f.endswith('.c')]
Run Code Online (Sandbox Code Playgroud)
或者概括为一个函数:
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')
Run Code Online (Sandbox Code Playgroud)
如果你确实需要完整的glob样式模式,你可以按照亚历克斯和布鲁诺的例子使用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')
Run Code Online (Sandbox Code Playgroud)
这就好比调用
Path.glob()与"**/"在给定的相对图案前面加:
import pathlib
for p in pathlib.Path("src").rglob("*.c"):
print(p)
Run Code Online (Sandbox Code Playgroud)
另请参阅@taleinat 的相关帖子和其他地方的类似帖子。
如果有人对此感兴趣,我已经介绍了最重要的三种建议方法。我在 globbed 文件夹中有大约 500K 个文件(总共),以及 2K 个与所需模式匹配的文件。
这是(非常基本的)代码
import glob
import json
import fnmatch
import os
from pathlib import Path
from time import time
def find_files_iglob():
return glob.iglob("./data/**/data.json", recursive=True)
def find_files_oswalk():
for root, dirnames, filenames in os.walk('data'):
for filename in fnmatch.filter(filenames, 'data.json'):
yield os.path.join(root, filename)
def find_files_rglob():
return Path('data').rglob('data.json')
t0 = time()
for f in find_files_oswalk(): pass
t1 = time()
for f in find_files_rglob(): pass
t2 = time()
for f in find_files_iglob(): pass
t3 = time()
print(t1-t0, t2-t1, t3-t2)
Run Code Online (Sandbox Code Playgroud)
我得到的结果是:
os_walk: ~3.6sec
rglob ~14.5sec
iglob: ~16.9sec
平台:Ubuntu 16.04,x86_64(核心i7),
import os, glob
for each in glob.glob('path/**/*.c', recursive=True):
print(f'Name with path: {each} \nName without path: {os.path.basename(each)}')
Run Code Online (Sandbox Code Playgroud)
glob.glob('*.c') :匹配所有.c以当前目录结尾的文件glob.glob('*/*.c') : 同 1glob.glob('**/*.c') : 只匹配.c以直接子目录结尾的所有文件,而不匹配当前目录中的所有文件glob.glob('*.c',recursive=True) : 同 1glob.glob('*/*.c',recursive=True) :同3glob.glob('**/*.c',recursive=True) :匹配.c以当前目录和所有子目录结尾的所有文件小智 6
最近我不得不用扩展名.jpg恢复我的照片.我运行了photorec并恢复了4579个目录,其中有220万个文件,有各种各样的扩展名.通过下面的脚本,我能够在几分钟内选择50133个文件havin .jpg扩展:
#!/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)
Run Code Online (Sandbox Code Playgroud)
Johan和Bruno提供了满足最低要求的出色解决方案.我刚刚发布了Formic,它实现了Ant FileSet和Globs,可以处理这个和更复杂的场景.您的要求的实施是:
import formic
fileset = formic.FileSet(include="/src/**/*.c")
for file_name in fileset.qualified_files():
print file_name
Run Code Online (Sandbox Code Playgroud)
基于其他答案,这是我当前的工作实现,它在根目录中检索嵌套的xml文件:
files = []
for root, dirnames, filenames in os.walk(myDir):
files.extend(glob.glob(root + "/*.xml"))
Run Code Online (Sandbox Code Playgroud)
我真的很开心python :)
对于 python 3.5 及更高版本
import glob
#file_names_array = glob.glob('path/*.c', recursive=True)
#above works for files directly at path/ as guided by NeStack
#updated version
file_names_array = glob.glob('path/**/*.c', recursive=True)
Run Code Online (Sandbox Code Playgroud)
进一步你可能需要
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'
Run Code Online (Sandbox Code Playgroud)
对于python> = 3.5,可以使用**,recursive=True:
import glob
for x in glob.glob('path/**/*.c', recursive=True):
print(x)
Run Code Online (Sandbox Code Playgroud)
如果递归为true,则该模式
**将匹配任何文件以及零个或多个directories和subdirectories。如果模式后跟一个os.sep,则仅目录和subdirectories匹配项。
| 归档时间: |
|
| 查看次数: |
590217 次 |
| 最近记录: |