2014-01-15 4 views
1

У меня есть каталог с файлами формата:возвращая последнюю версию файла в каталоге для конкретного формата

test_report-01-13-2014.11_53-en.zip 
test_report-12-04-2013.11_53-en.zip 

и мне нужно, чтобы вернуть последние файлы на основе даты в именах файлов не дата файл был последний раз коснулся. Если я сделаю это, я могу закончить с файлом 2013 года, что было бы неправильно. Я делаю следующее, но это не работает. Я передаю в следующих PARAMATERS:

mypath = "C:\\temp\\test\\" 
mypattern = "test_report-%m-%d-%Y*" 
myfile = getLatestFile(mypath, mypattern) 

def getLatestFile(path="./", pattern="*"): 
    fformat= path + pattern 
    archives = glob.glob(fformat) 

    if len(archives) > 0: 
     return archives[-1] 
    else: 
     return None 

любая идея, что может быть причиной этой проблемы?

+0

У вас есть контроль над соглашением именования файлов? Ответы ниже будут работать, но лучшее именование может обеспечить лучшую читаемость как с python, так и при листинге файлов в другом месте. – mhlester

+0

К сожалению, нет. Я застрял в формате. – Eric

+1

Достаточно честный; всегда стоит того! Ниже приведены ответы, которые должны работать тогда – mhlester

ответ

0

Смотрите Pythondocumentation:

os.listdir(path='.')

Возвращает список, содержащий имена записей в каталоге заданной траектории. Список находится в произвольном порядке и не содержит специальных записей '.' и «..», даже если они присутствуют в каталоге.

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

1

Порядок архивов произволен, но не только то, что ваши имена файлов не могут быть отсортированы в алфавитном порядке (месяц до года). Самый простой способ это sort списка с key функции, которая извлекает datetime объекта из файла:

import datetime 

def getDateFromFilename(filename): 
    try: 
     return datetime.datetime.strptime(timestamp[12:-7], '%m-%d-%Y.%H_%M') 
    except ValueError: 
     return -1 

archives.sort(key=getDateFromFilename) 
+0

. Это работает, но мне нужно также сделать это для test1_report test2_report и т. Д. ... Ключевым функциям принадлежит только один параметр. Итак, как я могу это сделать? – Eric

2

glob возвращает соответствующие пути в произвольном порядке, и он не понимает %m-%d-%Y (его не так умен).

Вам необходимо прочитать список путей, извлечь имя файла, а затем получить дату из имени файла. Это будет ключ, который вы будете использовать для сортировки списка файлов.

Вот один из способов сделать это:

import glob 
import os 
import datetime 

def sorter(path): 
    filename = os.path.basename(path) 
    return datetime.datetime.strptime(filename[12:22], '%m-%d-%Y') 

pattern = "test_report-*" 
search_path = r'C:\temp\test\' # or 'c:/temp/test/' 

file_list = glob.glob(pattern+search_path) 

# Order by the date 
ordered_list = sorted(file_list, key=sorter, reverse=True) 

os.path.basename является функцией, чтобы вернуть последний компонент пути; поскольку glob вернет полный путь, последним компонентом будет имя файла.

Поскольку ваше имя файла имеет фиксированный формат - вместо того, чтобы сбрасывать регулярные выражения, я просто захватил часть даты, нарезая имя файла и преобразовывая его в объект datetime.

Наконец, sortedвозвращает результат сортировки (нормальный sort метод является вместо рода). Ключевой функцией является то, что извлекает дату и возвращает ее, reverse=True требуется для получения возвращенного списка в порядке последнего.

Вы можете сократить код немного, передавая результат glob.glob непосредственно отсортирован:

ordered_list = sorted(glob.glob(pattern+search_path), key=sorter, reverse=True)

Чтобы объединить это с помощью функции вы написали:

import glob, os, datetime 

def sorter(path): 
    filename = os.path.basename(path) 
    return datetime.datetime.strptime(filename[12:22], '%m-%d-%Y') 

def getLatestFile(path="./", pattern="*"): 
    fformat = path + pattern 
    archives = glob.glob(fformat) 

    if len(archives): 
     return sorted(archives, key=sorter, reverse=True)[0] 
+0

Обратите внимание, что 'max (archives, key = sorted)' может использоваться здесь для сохранения 'sorted' –

0

Если бы сортировать свой список по названию, просто сделать sorted(archives = glob.glob(fformat))

+0

OP пытается сортировать по дате в имени файла, а не только по имени. Также ваш второй вариант сохранит None в архивах, потому что .sort() ничего не возвращает – mhlester

+0

А, извините. Обычно я пишу даты YYYY-MM-DD. Тогда достаточно соседей по имени. Я читал слишком быстро ... – Simon

0

Большое спасибо за ввод , Я использовал немного всего и закончил с этим, что отлично работает для моих целей.

def getDateFromFilename(filename): 
    try: 
     return datetime.datetime.strptime(filename, myPattern + '%m-%d-%Y.%H_%M-en.zip') 
    except ValueError: 
     return -1 

def getLatestFile(path, pattern): 
    files = sorted([f for f in os.listdir(myPath) if f.startswith(pattern)]) 
    files.sort(key=getDateFromFilename) 

    if len(files) > 0: 
     return files[-1] 
    else: 
     return None 
+0

, если myPattern должен был измениться, как я могу передать новые шаблоны? Могу ли я передать здесь параметры: files.sort (key = getDateFromFilename (имя файла, шаблон)) – Eric

Смежные вопросы