У меня есть каталог с кучей файлов внутри: eee2314
, asd3442
... и eph
.
Я хочу , чтобы исключить все файлы , которые начинаются с eph
с glob
функцией.
Как я могу это сделать?
У меня есть каталог с кучей файлов внутри: eee2314
, asd3442
... и eph
.
Я хочу , чтобы исключить все файлы , которые начинаются с eph
с glob
функцией.
Как я могу это сделать?
Ответы:
Шаблонные правила для glob не являются регулярными выражениями. Вместо этого они следуют стандартным правилам расширения пути Unix. Есть только несколько специальных символов: два разных символа подстановки и диапазоны символов поддерживаются [from glob ].
Таким образом, вы можете исключить некоторые файлы с шаблонами.
Например, чтобы исключить файлы манифестов (файлы, начинающиеся с _
) с помощью 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
не сработает, поэтому вам понадобится регулярное выражение
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']
Как насчет пропуска конкретного файла при итерации по всем файлам в папке! Код ниже пропустит все файлы Excel, которые начинаются с '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
.
В более общем плане, чтобы исключить файлы, которые не соответствуют некоторому регулярному выражению оболочки, вы можете использовать module 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)
Приведенное выше сначала сгенерирует список по заданному пути, а затем выскочит файлы, которые не удовлетворяют регулярному выражению с желаемым ограничением.
Как упоминалось в принятом ответе, вы не можете исключить шаблоны с помощью glob, поэтому ниже приведен метод фильтрации вашего результата glob.
Принятый ответ, вероятно, является лучшим питоническим способом сделать что-то, но если вы думаете, что понимание списка выглядит немного уродливо и все равно хотите сделать свой код максимально 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*"))
(В моем случае у меня было несколько кадров изображений, кадров смещения и плоских кадров в одном каталоге, и мне просто нужны были кадры изображений)
Если положение символа не важно, например, чтобы исключить файлы манифестов (где бы он ни находился _
) с помощью операций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.