Уточнение шаблона fnmatch для получения более конкретных результатов

#python #python-2.7

#python #python-2.7

Вопрос:

Совершенно новый для Python, исходящий из MATLAB. По сути, нет знаний UNIX или regexp.

У меня есть некоторые данные для обработки, отсортированные по папкам. Я хотел бы получить список файлов для обработки, поэтому я запрашиваю папку верхнего уровня и ищу все в этой папке и подпапках для соответствия. Между документацией для Python и различными вещами здесь, на SO, я проделал большую часть пути:

 from Tkinter import Tk
import tkFileDialog
import os
import fnmatch

def recursivedecodeprompt():
    root = Tk()
    root.withdraw()
    toplevel = tkFileDialog.askdirectory(title='Select Top Level Directory')

    filelist = []
    for root, dirnames, filenames in os.walk(toplevel):
        for filename in fnmatch.filter(filenames, 'LOG.*'):
            filelist.append(os.path.join(root, filename))

    return filelist
  

Мой вопрос касается строки шаблона. В моих папках может быть только LOG.001 файл, или в них могут быть LOG.001 , LOG.001.csv LOG.001.gps и т.д., Которым также соответствует мой текущий шаблон. Я думал, что смогу быть умным и использовать 'LOG.???' , но он возвращает тот же список.

Есть ли простой способ fnmatch игнорировать файлы с чем-либо, добавленным после 3-значного идентификатора? Есть ли более подходящий инструмент для этой работы?

Полусвязанный побочный вопрос: Есть ли способ разрешить изменение размера tkFileDialog.askdirectory() диалогового окна?

РЕДАКТИРОВАТЬ: чтобы уточнить, числовая часть имени файла может и будет меняться, поэтому у меня может быть LOG.001 , LOG.002 LOG.003 и т.д. Хотелось бы, чтобы это было менее раздражающее соглашение об именовании, но именно так оно выходит из устройства.

Комментарии:

1. Попробуйте использовать re re.findall("LOG.001.*",filenames) , никогда не использовал fnmatch, но, возможно, можно использовать то же выражение.

2. Я не думаю, re.findall() что его можно использовать в списке

3. его можно использовать, если выполнить итерацию по списку

4. @PadraicCunningham Я хочу исключить что-либо с другим расширением, поэтому я хочу только LOG.001 , LOG.002 и т.д.

Ответ №1:

Использование re:

 filnames = ["LOG.001","LOG.002","LOG.001.csv","LOG.003.csv","LOG.1002"]
print [x for x in filnames if re.search("LOG.d $",x)]

['LOG.001', 'LOG.002', 'LOG.1002']
  

Ответ №2:

Из того, что вы говорите, кажется, что только допустимые имена файлов имеют длину ровно семь символов. Таким образом, казалось бы, самым простым способом является включение

 if len(filename) != 7:
    continue
  

в качестве первой строки цикла. Это завершит текущую итерацию цикла, если только имя файла действительно не имеет длину всего семь символов. Регулярные выражения не требуются!

Комментарии:

1. OP ищет различные файлы журналов, которые начинаются с «LOG.001» и могут заканчиваться .gps,.csv и т.д. Поэтому я не понимаю, как поиск длины связан с вопросом.

2. В OP конкретно говорится, что он хочет игнорировать любые файлы, которые не просто называются «LOG.NNN», поэтому, пока нет файлов «LOG.gps», я не понимаю, почему это решение не будет работать. Жалоба, похоже, заключается в том, что в настоящее время сопоставляются имена файлов, такие как «Log.NNN.gps». Или я все еще неправильно понимаю вопрос?

3. @holdenweb да, я неправильно понял вопрос.

4. Я вполне согласен, но хотел, чтобы вы быстро продвигались вперед, прежде чем указывать альтернативы. @Padraic Я часто делал то же самое сам, не беспокойтесь.

5. Ах, на самом деле я вижу, что Падрайк уже предоставил элегантный способ, поэтому я просто поддержу его ответ.