मैं अंदर फाइलों का एक समूह के साथ एक निर्देशिका है: eee2314
, asd3442
... और eph
।
मैं फ़ंक्शन के eph
साथ शुरू होने वाली सभी फ़ाइलों को बाहर करना चाहता हूं glob
।
मैं यह कैसे कर सकता हूं?
मैं अंदर फाइलों का एक समूह के साथ एक निर्देशिका है: eee2314
, asd3442
... और eph
।
मैं फ़ंक्शन के eph
साथ शुरू होने वाली सभी फ़ाइलों को बाहर करना चाहता हूं glob
।
मैं यह कैसे कर सकता हूं?
जवाबों:
ग्लोब के लिए पैटर्न नियम नियमित अभिव्यक्ति नहीं हैं। इसके बजाय, वे मानक यूनिक्स पथ विस्तार नियमों का पालन करते हैं। केवल कुछ विशेष वर्ण हैं: दो अलग-अलग वाइल्ड-कार्ड, और वर्ण श्रेणियां [ ग्लोब से ] समर्थित हैं ।
तो आप पैटर्न के साथ कुछ फ़ाइलों को बाहर कर सकते हैं।
उदाहरण के लिए _
ग्लोब के साथ मैनिफ़ेस्ट फ़ाइल (फ़ाइलों से शुरू होने वाली ) को बाहर करने के लिए , आप उपयोग कर सकते हैं:
files = glob.glob('files_path/[!_]*')
eph
लेकिन कुछ और के साथ शुरू हो सकती हैं। उदाहरण के लिए [!e][!p][!h]
शुरू होने वाली फ़ाइलों को फ़िल्टर करेगा eee
।
आप सेट घटा सकते हैं:
set(glob("*")) - set(glob("eph*"))
set(glob("*")) - set(glob("eph*"))
(और "eph *" के अंत में सूचना दें)
list(set(glob("*")) - set(glob("eph")))
आप glob
फ़ंक्शन के साथ पैटर्न को बाहर नहीं कर सकते , ग्लब्स केवल समावेश पैटर्न के लिए अनुमति देते हैं । ग्लोबिंग सिंटैक्स बहुत सीमित है (यहां तक कि एक [!..]
चरित्र वर्ग को एक चरित्र से मेल खाना चाहिए , इसलिए यह प्रत्येक वर्ण के लिए एक समावेश पैटर्न है जो कक्षा में नहीं है)।
आपको अपना फ़िल्टर करना होगा; एक सूची की समझ आमतौर पर यहाँ अच्छी तरह से काम करती है:
files = [fn for fn in glob('somepath/*.txt')
if not os.path.basename(fn).startswith('eph')]
iglob
मेमोरी में पूरी सूची को स्टोर करने से बचने के लिए यहां उपयोग करें
iglob
सूचियों का उत्पादन करता है ; आप सभी आलसी फ़िल्टर का मूल्यांकन करते हैं। यह स्मृति पदचिह्न को कम करने में मदद नहीं करेगा।
os.listdir()
परिणाम में स्मृति में रखा जाता है जैसे कि आप इसे पुनरावृत्त करते हैं। लेकिन somepath/*.txt
सभी फ़ाइलनामों को एक निर्देशिका में मेमोरी में पढ़ना होगा, फिर उस सूची को केवल उस मैच तक कम करें।
glob.glob(x) = list(glob.iglob(x))
। अधिक उपरि नहीं, लेकिन फिर भी अच्छा है।
खेल के लिए देर से लेकिन आप वैकल्पिक रूप filter
से एक परिणाम के लिए एक अजगर लागू कर सकते हैं glob
:
files = glob.iglob('your_path_here')
files_i_care_about = filter(lambda x: not x.startswith("eph"), files)
या एक उचित रेगेक्स खोज, आदि के साथ लैम्ब्डा की जगह ...
संपादित करें: मुझे बस एहसास हुआ कि यदि आप पूर्ण पथों का उपयोग नहीं कर रहे हैं startswith
, तो आपको एक regex की आवश्यकता होगी
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']
कैसे फ़ोल्डर में सभी फ़ाइलों पर पुनरावृत्ति करते समय विशेष फ़ाइल लंघन के बारे में! नीचे दिया गया कोड सभी एक्सेल फ़ाइलों को छोड़ देगा जो 'eph' से शुरू होती हैं।
import glob
import re
for file in glob.glob('*.xlsx'):
if re.match('eph.*\.xlsx',file):
continue
else:
#do your stuff here
print(file)
इस तरह आप एक फ़ोल्डर में फ़ाइलों के एक विशेष सेट को शामिल / बाहर करने के लिए अधिक जटिल रीगेक्स पैटर्न का उपयोग कर सकते हैं।
के साथ तुलना करें glob
, मैं सुझाता हूं pathlib
, एक पैटर्न को फ़िल्टर करना बहुत सरल है।
from pathlib import Path
p = Path(YOUR_PATH)
filtered = [x for x in p.glob("**/*") if not x.name.startswith("eph")]
और यदि आप अधिक जटिल पैटर्न को फ़िल्टर करना चाहते हैं, तो आप ऐसा करने के लिए एक फ़ंक्शन को परिभाषित कर सकते हैं, जैसे:
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)]
उस कोड का उपयोग करें, आप उन सभी फ़ाइलों को फ़िल्टर कर सकते हैं जो शुरू होती हैं eph
या जिनके साथ शुरू होती हैं epi
।
आम तौर पर, उन फ़ाइलों को बाहर करने के लिए जो कुछ शेल रीजैक्सप का अनुपालन नहीं करते हैं, आप मॉड्यूल का उपयोग कर सकते हैं 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)
उपरोक्त पहले एक दिए गए पथ से एक सूची उत्पन्न करेगा और उन फ़ाइलों को पॉप आउट करेगा जो वांछित बाधा के साथ नियमित अभिव्यक्ति को संतुष्ट नहीं करेंगे।
जैसा कि स्वीकृत उत्तर द्वारा बताया गया है, आप ग्लोब के साथ पैटर्न को बाहर नहीं कर सकते हैं, इसलिए निम्न आपके ग्लोब परिणाम को फ़िल्टर करने की एक विधि है।
स्वीकृत उत्तर चीजों को करने के लिए शायद सबसे अच्छा पायथोनिक तरीका है, लेकिन अगर आपको लगता है कि सूची की समझ थोड़ी बदसूरत है और अपने कोड को अधिकतम रूप से संख्यात्मक रूप से बनाना चाहते हैं (जैसे मैंने किया) तो आप ऐसा कर सकते हैं (लेकिन ध्यान दें कि यह शायद कम कुशल है सूची समझने की विधि से):
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*"))
(मेरे मामले में, मेरे पास कुछ छवि फ़्रेम, पूर्वाग्रह फ़्रेम, और फ्लैट फ़्रेम सभी एक निर्देशिका में थे और मुझे बस छवि फ़्रेम चाहिए था)
यदि चरित्र की स्थिति महत्वपूर्ण नहीं है, तो यह उदाहरण के लिए है कि मैनिफ़ेस्ट फ़ाइल (जहाँ भी यह पाया जाता है _
) को बाहर करना glob
और re
- नियमित अभिव्यक्ति संचालन के साथ , आप उपयोग कर सकते हैं:
import glob
import re
for file in glob.glob('*.txt'):
if re.match(r'.*\_.*', file):
continue
else:
print(file)
या अधिक सुरुचिपूर्ण तरीके से - list comprehension
filtered = [f for f in glob.glob('*.txt') if not re.match(r'.*\_.*', f)]
for mach in filtered:
print(mach)
आप नीचे दी गई विधि का उपयोग कर सकते हैं:
# 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.