2013-12-17 132 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

是的,這是做了排除某些文件擴展名的技巧。謝謝! –