İçeriye dosyaların bir grup ile bir dizin var: eee2314
, asd3442
... ve eph
.
Ben ile başlayan tüm dosyaları dışlamak istediğiniz eph
ile glob
fonksiyonu.
Nasıl yapabilirim?
İçeriye dosyaların bir grup ile bir dizin var: eee2314
, asd3442
... ve eph
.
Ben ile başlayan tüm dosyaları dışlamak istediğiniz eph
ile glob
fonksiyonu.
Nasıl yapabilirim?
Yanıtlar:
Glob için kalıp kuralları normal ifadeler değildir. Bunun yerine, standart Unix yol genişletme kurallarını izlerler. Yalnızca birkaç özel karakter vardır: iki farklı joker karakter ve karakter aralıkları [ glob'dan ] desteklenir .
Böylece bazı dosyaları kalıplarla dışarıda bırakabilirsiniz.
Örneğin, manifest dosyalarını (ile başlayan dosyalar _
) glob ile hariç tutmak için şunları kullanabilirsiniz:
files = glob.glob('files_path/[!_]*')
eph
ancak başka herhangi bir şeyle başlayabilen dosyaları hariç tutma . örneğin [!e][!p][!h]
ile başlayan dosyaları filtreleyecektir eee
.
Setleri düşebilirsiniz:
set(glob("*")) - set(glob("eph*"))
set(glob("*")) - set(glob("eph*"))
(ve "
list(set(glob("*")) - set(glob("eph")))
glob
İşlevle kalıpları hariç tutamazsınız , globlar yalnızca dahil etme kalıplarına izin verir . Sözdizimi globbing çok sınırlıdır (hatta bir [!..]
karakter sınıfı gerekir bir nedenle, bir karakteri eşleştirmek içerme desen sınıfta değil her karakter için).
Kendi filtrelemenizi yapmanız gerekecek; burada bir liste anlayışı genellikle işe yarar:
files = [fn for fn in glob('somepath/*.txt')
if not os.path.basename(fn).startswith('eph')]
iglob
Listenin tamamını bellekte saklamaktan kaçınmak için burayı kullanın
iglob
listeler üretir ; tek yapmanız gereken filtreyi tembelce değerlendirmek. Bellek ayak izini azaltmaya yardımcı olmaz.
os.listdir()
sonuç bellekte tutulur. Ancak somepath/*.txt
bellekteki bir dizindeki tüm dosya adlarını okumalı, sonra bu listeyi yalnızca eşleşenlere indirgemelidir.
glob.glob(x) = list(glob.iglob(x))
,. Fazla bir yük değil ama yine de bilmek güzel.
Oyuna geç kaldınız, ancak alternatif filter
olarak aşağıdaki sonuca bir python uygulayabilirsiniz glob
:
files = glob.iglob('your_path_here')
files_i_care_about = filter(lambda x: not x.startswith("eph"), files)
veya lambda'yı uygun bir normal ifade aramasıyla vb. değiştirmek ...
DÜZENLEME: Tam yolları kullanıyorsanız startswith
bunun işe yaramayacağını anladım , bu nedenle bir normal ifadeye ihtiyacınız olacak
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']
Klasördeki tüm dosyaları yinelerken belirli bir dosyayı atlamaya ne dersiniz! Aşağıdaki kod, 'eph' ile başlayan tüm excel dosyalarını atlar
import glob
import re
for file in glob.glob('*.xlsx'):
if re.match('eph.*\.xlsx',file):
continue
else:
#do your stuff here
print(file)
Bu şekilde, bir klasöre belirli bir dosya kümesini dahil etmek / hariç tutmak için daha karmaşık normal ifade kalıplarını kullanabilirsiniz.
Karşılaştırın glob
, tavsiye ederim pathlib
, bir kalıbı filtrelemek çok basittir.
from pathlib import Path
p = Path(YOUR_PATH)
filtered = [x for x in p.glob("**/*") if not x.name.startswith("eph")]
ve daha karmaşık deseni filtrelemek istiyorsanız, bunu yapmak için bir işlev tanımlayabilirsiniz, örneğin:
def not_in_pattern(x):
return (not x.name.startswith("eph")) and not x.name.startswith("epi")
filtered = [x for x in p.glob("**/*") if not_in_pattern(x)]
bu kodu kullanın, ile başlayan eph
veya başlayan tüm dosyaları filtreleyebilirsiniz epi
.
Daha genel olarak, bazı kabuk regexp'lerine uymayan dosyaları dışlamak için modülü kullanabilirsiniz 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)
Yukarıdakiler önce belirli bir yoldan bir liste oluşturacak ve ardından normal ifadeyi istenen kısıtlamayla karşılamayan dosyaları açacaktır.
Kabul edilen yanıtta belirtildiği gibi, glob ile kalıpları hariç tutamazsınız, bu nedenle aşağıdaki glob sonucunuzu filtrelemek için bir yöntemdir.
Kabul edilen cevap muhtemelen bir şeyler yapmanın en iyi pitonik yoludur, ancak liste anlamalarının biraz çirkin göründüğünü düşünüyorsanız ve kodunuzu yine de en üst düzeyde numpythonic yapmak istiyorsanız (benim yaptığım gibi), o zaman bunu yapabilirsiniz (ancak bunun muhtemelen daha az verimli olduğunu unutmayın. liste anlama yönteminden daha fazla):
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*"))
(Benim durumumda, hepsi tek bir dizinde bazı görüntü çerçeveleri, önyargı çerçeveleri ve düz çerçeveler vardı ve sadece görüntü çerçevelerini istedim)
Karakterin konumu önemli değilse , örneğin manifesto dosyalarını (nerede bulunursa bulunsun _
) glob
ve re
- normal ifade işlemleriyle hariç tutmak için , şunları kullanabilirsiniz:
import glob
import re
for file in glob.glob('*.txt'):
if re.match(r'.*\_.*', file):
continue
else:
print(file)
Veya daha zarif bir şekilde - list comprehension
filtered = [f for f in glob.glob('*.txt') if not re.match(r'.*\_.*', f)]
for mach in filtered:
print(mach)
Aşağıdaki yöntemi kullanabilirsiniz:
# Get all the files
allFiles = glob.glob("*")
# Files starting with eph
ephFiles = glob.glob("eph*")
# Files which doesnt start with eph
noephFiles = []
for file in allFiles:
if file not in ephFiles:
noephFiles.append(file)
# noepchFiles has all the file which doesnt start with eph.
Thank you.