2013-12-17 129 views

回答

26

您不能用glob函数排除图案,globs只允许包含图案。 Globbing syntax是非常有限的(即使[!..]字符类必须匹配一个字符,所以它是一个包含模式对于不在该类中的每个字符)。

你必须做你自己的过滤;列表理解通常在这里很好地工作:

files = [fn for fn in glob('somepath/*.txt') 
     if not os.path.basename(fn).startswith('eph')] 
+0

使用''这里iglob''以避免在内存中存储 –

+0

@Hardex的完整列表:在内部,'iglob '生产清单*无论如何*;你所做的只是懒惰地评估过滤器。这无助于减少内存占用。 –

+0

@Hardex:如果你在*目录名中使用glob,那么你会得到一个点,那么在迭代时,最多只有一个'os.listdir()'结果保存在内存中。但'somepath/*。txt'必须读取内存中的一个目录中的所有文件名,然后将该列表减少为仅匹配的目录。 –

18

可以扣除集:

set(glob("*")) - set(glob("eph")) 
+1

非常有趣的解决方案!但是我的情况会非常缓慢地读两次。另外,如果网络目录中文件夹的内容很大,则会再次变慢。但无论如何,真的很方便。 –

+0

你的操作系统应该缓存文件系统请求,所以没有那么糟糕:) – neutrinus

+0

尝试这个我自己,我刚刚得到TypeError:不支持的操作数类型为 - :'list'和'list' –

1

更一般地,以排除不符合一些正则表达式外壳文件,你可以使用模块fnmatch

import fnmatch 

file_list = glob('somepath')  
for ind, ii in enumerate(file_list): 
    if not fnmatch.fnmatch(ii, 'bash_regexp_with_exclude'): 
     file_list.pop(ind) 

以上将首先从给定路径生成列表,然后弹出不满足具有所需约束的正则表达式的文件。

0

太迟了,但你可以只交替应用蟒蛇filterglob结果:

files = glob.iglob('your_path_here') 
files_i_care_about = filter(lambda x: not x.startswith("eph"), files) 

或用适当的正则表达式搜索替换拉姆达,等等

编辑:我刚刚意识到,如果你使用的完整路径的startswith将无法​​正常工作,所以你需要一个正则表达式

In [10]: a 
Out[10]: ['/some/path/foo', 'some/path/bar', 'some/path/eph_thing'] 

In [11]: filter(lambda x: not re.search('/eph', x), a) 
Out[11]: ['/some/path/foo', 'some/path/bar'] 
0

正如接受的答案所述,您不能使用glob排除模式,因此以下是过滤glob结果的方法。

接受的答案可能是最好的pythonic方式来做事情,但如果你认为列表解析看起来有点丑陋,并且想要使你的代码最大化numpythonic无论如何(就像我做的那样),那么你可以做到这一点(但请注意,这可能比列表解析方法效率较低):

import glob 

data_files = glob.glob("path_to_files/*.fits") 

light_files = np.setdiff1d(data_files, glob.glob("*BIAS*")) 
light_files = np.setdiff1d(light_files, glob.glob("*FLAT*")) 

(在我的情况,我有一些图像帧,偏置框架和平面框架都在同一个目录中,我只是想将图像帧)

40

glob的模式规则不是正则表达式。相反,他们遵循标准的Unix路径扩展规则。只有几个特殊字符:两个不同的通配符,并支持字符范围[来自glob]。

所以你可以排除一些带有模式的文件。
例如,要排除清单文件(文件开始_)与水珠,你可以使用:

files = glob.glob('files_path/[!_]*') 
+0

这必须在官方文档中,请有人将此添加到https://docs.python.org/3.5/library/glob.html#glob.glob –

+0

是的,这是做了排除某些文件扩展名的技巧。谢谢! –