Есть ли альтернатива функции glob.glob (), независимая от файловой системы? [Дубликат]

Использование базовой функции R aggregate:

aggregate(value ~ name, dat1, I)

# name           value.1  value.2  value.3  value.4
#1 firstName      0.4145  -0.4747   0.0659   -0.5024
#2 secondName    -0.8259   0.1669  -0.8962    0.1681
28
задан andreas-h 16 November 2011 в 13:59
поделиться

4 ответа

Используйте не зависящие от регистров регулярные выражения вместо шаблонов glob. fnmatch.translate генерирует регулярное выражение из шаблона glob, поэтому

re.compile(fnmatch.translate(pattern), re.IGNORECASE)

дает вам нечувствительную к регистру версию шаблона glob в качестве скомпилированного RE.

Имейте в виду, что если файловая система размещается в ящике Linux в Unix-подобной файловой системе, пользователи смогут создавать файлы foo, Foo и FOO в том же каталоге.

22
ответ дан Fred Foo 22 August 2018 в 15:55
поделиться
  • 1
    cool 8) есть ли функция, чтобы затем вернуть список совпадающих имен файлов, или мне нужно вручную пройти каскады os.listdir ()? – andreas-h 16 November 2011 в 15:14
  • 2
    после 2 часов возиться с os.walk, я в недоумении. не могли бы вы посоветовать немного больше? мне сложно определить цикл вокруг dirs, соответствующий re и ломаться соответствующим образом. вероятно, не мой день :( – andreas-h 16 November 2011 в 17:44
  • 3
    @andreash: os.walk возвращает тройки (basepath, dirs, files) s.t. вы можете получить относительный путь к файлу или файлу, присоединив его (os.path.join) с помощью basepath. Затем вы можете попытаться сопоставить результат с вашим шаблоном. – Fred Foo 16 November 2011 в 17:51
  • 4
    Я приму этот ответ, поскольку он дает правильный ответ. однако, по соображениям скорости, я решил использовать более индивидуальную комбинацию os.walk и os.listdir. – andreas-h 18 January 2012 в 14:50

Вы можете заменить каждый алфавитный символ c на [cC], через

import glob
def insensitive_glob(pattern):
    def either(c):
        return '[%s%s]' % (c.lower(), c.upper()) if c.isalpha() else c
    return glob.glob(''.join(map(either, pattern)))
38
ответ дан Geoffrey Irving 22 August 2018 в 15:55
поделиться
  • 1
    Чтобы быть немного более питоническим ... или хотя бы сделать pylint счастливым return glob.glob(''.join(either(char) for char in pattern)) – shao.lo 26 April 2015 в 01:55
  • 2
    shao.lo: Да, у этого есть преимущество, чтобы быть длиннее. – Geoffrey Irving 26 April 2015 в 03:55
  • 3
    Это решение имеет серьезные недостатки, поэтому будьте осторожны. Во-первых, glob() не сможет использовать этот тип шаблона для буквы диска Windows. Затем это применимо при использовании «магии». такие папки, как "системный" папка. – payet_s 22 June 2016 в 11:00
  • 4

В зависимости от вашего случая вы можете использовать .lower() для обоих шаблонов файлов и результатов из списка папок и только затем сравнить шаблон с именем файла

1
ответ дан HCLivess 22 August 2018 в 15:55
поделиться

Не рекурсивно

Чтобы получить файлы (и только файлы) каталога «path», с «globexpression»:

list_path = [i for i in os.listdir(path) if os.path.isfile(os.path.join(path, i))]
result = [os.path.join(path, j) for j in list_path if re.match(fnmatch.translate(globexpression), j, re.IGNORECASE)]

Рекурсивно

с прогулкой:

result = []
for root, dirs, files in os.walk(path, topdown=True):
  result += [os.path.join(root, j) for j in files \
             if re.match(fnmatch.translate(globexpression), j, re.IGNORECASE)]

Лучше также скомпилировать регулярное выражение, поэтому вместо

re.match(fnmatch.translate(globexpression)

выполните (перед циклом):

reg_expr = re.compile(fnmatch.translate(globexpression), re.IGNORECASE)

, а затем заменить в цикле:

  result += [os.path.join(root, j) for j in files if re.match(reg_expr, j)]
6
ответ дан Raffi 22 August 2018 в 15:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: