Страницы

Поиск по вопросам

среда, 11 декабря 2019 г.

Выбор последнего по дате файла из каталога

#python


Изучаю Python, пытаюсь написать скрипт, который из определенной папки берет файл,
который создался поздней других. Как это сделать?
    


Ответы

Ответ 1



Пусть задан какой-то путь: path = r'C:\Python27' Нужно получить список файлов по этому пути: import os files = os.listdir(path) На этом этапе желательно проверить, что список файлов не пустой. Делаем просто if files:, а все что расписано ниже - идет внутри блока if. Превратим просто список файлов в список файлов с путями: files = [os.path.join(path, file) for file in files] Функция os.path.join() "прикрепляет" путь к имени файла. В зависимости от системы данная функция вставляет между путем и файлом либо прямой слеш, либо обратный, либо вообще ничего, если слеш уже есть в конце пути. Оставляем в списке только файлы: files = [file for file in files if os.path.isfile(file)] Время создания файла будем определять функцией os.path.getctime(). Нужно найти файл, у которого дата модификации максимальна. Для этого воспользуемся функцией max с дополнительным параметром key, позволяющим задать функцию, которая будет применяться к каждому объекту из списка, минимальное будет определяться по соответствующим возвращаемым значениям: >>> max(files, key=os.path.getctime) 'C:\\Python27\\LICENSE.txt' В других ответах вижу sort либо sorted. Почему не применить его? Все просто: зачем сортировать список (возможно, большой), когда нужно всего лишь один раз пройти по нему и найти максимальное.

Ответ 2



import os path = '/path/to/you/dir' # Путь к вашей папке # Получим список имен всего содержимого папки # и превратим их в абсолютные пути dir_list = [os.path.join(path, x) for x in os.listdir(path)] if dir_list: # Создадим список из путей к файлам и дат их создания. date_list = [[x, os.path.getctime(x)] for x in dir_list] # Отсортируем список по дате создания в обратном порядке sort_date_list = sorted(date_list, key=lambda x: x[1], reverse=True) # Выведем первый элемент списка. Он и будет самым последним по дате print sort_date_list[0][0]

Ответ 3



..скрипт, который из определенной папки берет файл, который создался поздней других. #!/usr/bin/env python3 import os import sys folder = sys.argv[1] if len(sys.argv) > 1 else os.curdir entry = max((e for e in os.scandir(folder) if e.is_file(follow_symlinks=False)), key=lambda e: getattr(e.stat(), 'st_birthtime', None) or e.stat().st_ctime) print(entry.path) Смысл st_ctime зависит от системы: на Windows — это время создания файла на POSIX — это время последнего изменения мета-данных у файла (что может отличаться от даты создания файла) st_birthtime это время создания файла на некоторых системах таких как FreeBSD. На Linux некоторые файловые системы такие как ext4 также сохраняют crtime (не путайте с ctime) -- поэтому, если обязательно нужна именно дата создания, то можно что-то вроде xstat bash функции использовать (она реализована поверх debugfs и stat -- сама по себе stat команда не возвращает Birth time на моей системе). Чтобы найти файл, который был изменён последним, нужно использовать st_mtime атрибут. Если сохранить вышеприведённый Питон код в файл last_created.py и положить этот файл куда-нибудь в PYTHONPATH (sys.path), то чтобы узнать какой файл был создан последним в папке "здесь путь к папке", можно выполнить команду: C:\> py -m last_created "здесь путь к папке" Если .py в %PATHEXT% и py.exe настроен запускать файлы Питона (assoc .py, ftype Python.File), то можно выполнить просто: C:\> last_created "здесь путь к папке" Если необходимо следить за вновь созданными файлами в папке в реальном времени, то чтобы избежать постоянного перебора всех файлов в папке, можно использовать watchdog библиотеку, которая позволяет эффективно следить за изменениями в файловой системе (выполнять действия в ответ на события) и поддерживает разные платформы. Чтобы установить: С:\> py -m pip install watchdog Чтобы выводить на экран любые изменения в заданном дереве директорий: $ watchmedo log "здесь путь к папке" Вот версия last_created.py, которая поддерживает старые версии Питона (Python 2/3): #!/usr/bin/env python """Find the last created file in a given directory.""" import os import sys import stat folder = sys.argv[1] if len(sys.argv) > 1 else os.curdir files = (os.path.join(folder, name) for name in os.listdir(folder)) entries = ((path, os.lstat(path)) for path in files) # don't follow symlinks path, _ = max((e for e in entries if stat.S_ISREG(e[1].st_mode)), # find regular files key=lambda e: getattr(e[1], 'st_birthtime', None) or e[1].st_ctime) print(path) На Питоне 2 на Винде, чтобы не иметь проблем с Юникодными именами, следует использовать Unicode Win32 API: GetCommandLineW(), CommandLineToArgvW() (Python 3 делает это автоматически). См. Read Unicode characters from command-line arguments in Python 2.x on Windows. С этим изменением код работает даже, если имена не могут быть представлены в кодировке, используемой в текущей локали (PEP 383) на всех платформах (Python 2/3, Windows/POSIX). Поведение данного кода при возникновении ошибок (файл исчез или нет прав доступа к файлу) отличается от первого примера, где e.is_file() игнорирует FileNotFoundError. os.path.isfile() функция, используемая в других ответах, возвращает False при возникновении любых OSError ошибок (если хочется этого поведения, то можно явно обернуть os.lstat(), e.is_file() вызовы в try/except блоки). Дополнительно, в отличии примеров кода в этом ответе, os.path.isfile(), os.path.getctime() следуют по цепочке symlinks, если необходима информация по самой записи в каталоге, то можно os.path.islink() и os.lstat() вызывать. Версия, использующая os.scandir() может быть быстрее версии с os.listdir(). Также os.scandir() может работать для очень больших директорий не загружая все записи в память сразу как это делает os.listdir().

Ответ 4



Один из методов решения данной задачи может выглядеть, например, так: import glob import os def last_modified_file(folder): files = list(filter(os.path.isfile, glob.glob(folder + "/*"))) if len(files) > 0: files.sort(key=lambda x: os.path.getmtime(x), reverse=True) return files[0] else: return None file_name = last_modified_file("C:/Windows/System32") if file_name: print(file_name) else: print("No files in this folder.") Можно записать всё в одну строку, используя генераторы списков и функцию max: max([file for file in glob.iglob(folder + "/*") if os.path.isfile(file)], key=os.path.getmtime, default=None) Но у вышеперечисленных решений есть недостаток - большой расход памяти на хранение списка полученных файлов. Чтобы уменьшить расход памяти, можно использовать итераторы: def last_modified_file2(folder): result = None date = None for name in glob.iglob(folder + "/*"): if os.path.isfile(name): if not result: result = name date = os.path.getmtime(name) else: date2 = os.path.getmtime(name) if date2 > date: result = name date = date2 return result

Ответ 5



Время создания файла можно узнать функцией os.stat(path, *, dir_fd=None, follow_symlinks=True). Потом простенький цикл fn = "" day = 0 for n in glob.iglob("*.*"): if os.path.isdir(n): continue cday = os.stat(n).st_ctime if day

Ответ 6



Если используется линукс то можно так: import commands newest_file = commands.getoutput("ls /path/to/your/dir -apt1 | grep -v / | head -n 1") Не то, чтобы совсем питон, но максимально коротко.

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

Отправить комментарий