Как получить список каталогов, отсортированный по дате создания в Python?


129

Как лучше всего получить список всех файлов в каталоге, отсортированный по дате [создано | изменено] с использованием Python на машине Windows?

Ответы:


79

Обновление : для сортировки dirpathзаписей по дате модификации в Python 3:

import os
from pathlib import Path

paths = sorted(Path(dirpath).iterdir(), key=os.path.getmtime)

(поместите здесь ответ @ Pygirl для большей наглядности)

Если у вас уже есть список имен файлов files, чтобы отсортировать его по времени создания в Windows:

files.sort(key=os.path.getctime)

Список файлов, которые вы можете получить, например, используя, globкак показано в ответе @Jay .


старый ответ Вот более подробная версия @Greg Hewgillответа . Он наиболее соответствует требованиям вопроса. Он делает различие между датами создания и изменения (по крайней мере, в Windows).

#!/usr/bin/env python
from stat import S_ISREG, ST_CTIME, ST_MODE
import os, sys, time

# path to the directory (relative or absolute)
dirpath = sys.argv[1] if len(sys.argv) == 2 else r'.'

# get all entries in the directory w/ stats
entries = (os.path.join(dirpath, fn) for fn in os.listdir(dirpath))
entries = ((os.stat(path), path) for path in entries)

# leave only regular files, insert creation date
entries = ((stat[ST_CTIME], path)
           for stat, path in entries if S_ISREG(stat[ST_MODE]))
#NOTE: on Windows `ST_CTIME` is a creation date 
#  but on Unix it could be something else
#NOTE: use `ST_MTIME` to sort by a modification date

for cdate, path in sorted(entries):
    print time.ctime(cdate), os.path.basename(path)

Пример:

$ python stat_creation_date.py
Thu Feb 11 13:31:07 2009 stat_creation_date.py

1
Это сработало отлично. Я пытаюсь сравнить два каталога cdate друг с другом. Есть ли способ сравнить секунды между двумя cdates?
Федерер

@malcmcmul: cdateчисло секунд с плавающей точкой с начала эпохи.
jfs

4
Это работает, но наиболее краткое решение находится на stackoverflow.com/a/4500607/68534
jmoz

@jmoz: ты имеешь в виду вот так . Решение, которое вы ссылаетесь, неверное: оно не фильтрует обычные файлы. Примечание: мое решение вызывается statодин раз для каждого dir.entry.
jfs

Простите, ссылка, предоставленная Sabastian, еще более лаконична! Спасибо.
jmoz

148

Я делал это в прошлом для сценария Python, чтобы определить последние обновленные файлы в каталоге:

import glob
import os

search_dir = "/mydir/"
# remove anything from the list that is not a file (directories, symlinks)
# thanks to J.F. Sebastion for pointing out that the requirement was a list 
# of files (presumably not including directories)  
files = list(filter(os.path.isfile, glob.glob(search_dir + "*")))
files.sort(key=lambda x: os.path.getmtime(x))

Это должно делать то, что вы ищете, на основе файла mtime.

РЕДАКТИРОВАТЬ : обратите внимание, что вы также можете использовать os.listdir () вместо glob.glob (), если хотите - причина, по которой я использовал glob в моем исходном коде, заключалась в том, что я хотел использовать glob только для поиска файлов с определенным набором расширений файлов, для которых больше подходит glob (). Вот как это будет выглядеть для использования listdir:

import os

search_dir = "/mydir/"
os.chdir(search_dir)
files = filter(os.path.isfile, os.listdir(search_dir))
files = [os.path.join(search_dir, f) for f in files] # add path to each file
files.sort(key=lambda x: os.path.getmtime(x))

glob () хорош, но имейте в виду, что он пропускает файлы, начинающиеся с точки. Системы * nix обрабатывают такие файлы как скрытые (таким образом, исключая их из списков), но в Windows они являются обычными файлами.
efotinis 03

Эти решения не исключают каталоги из списка.
Константин

В вашем решении os.listdir отсутствует os.path.join: files.sort (lambda x, y: cmp (os.path.getmtime (os.path.join (search_dir, x)), os.path.getmtime (os .path.join (search_dir, y))))
Питер Хоффманн,

files.sort(key=lambda fn: os.path.getmtime(os.path.join(search_dir, fn)))
jfs

22
Просто files.sort(key=os.path.getmtime)должно работать (без lambda).
jfs

31

Есть os.path.getmtimeфункция, которая показывает количество секунд с начала эпохи и должна быть быстрее, чем os.stat.

import os 

os.chdir(directory)
sorted(filter(os.path.isfile, os.listdir('.')), key=os.path.getmtime)

23

Вот моя версия:

def getfiles(dirpath):
    a = [s for s in os.listdir(dirpath)
         if os.path.isfile(os.path.join(dirpath, s))]
    a.sort(key=lambda s: os.path.getmtime(os.path.join(dirpath, s)))
    return a

Сначала мы создаем список имен файлов. isfile () используется для пропуска каталогов; его можно не указывать, если необходимо включить каталоги. Затем мы сортируем список на месте, используя дату изменения в качестве ключа.


Оно отсортировано от самых старых к самым новым. Когда мне a[-5:]
Дэниел Батлер

20

Вот однострочник:

import os
import time
from pprint import pprint

pprint([(x[0], time.ctime(x[1].st_ctime)) for x in sorted([(fn, os.stat(fn)) for fn in os.listdir(".")], key = lambda x: x[1].st_ctime)])

Это вызывает os.listdir () для получения списка имен файлов, затем вызывает os.stat () для каждого из них, чтобы получить время создания, а затем выполняет сортировку по времени создания.

Обратите внимание, что этот метод вызывает os.stat () только один раз для каждого файла, что будет более эффективно, чем вызов его для каждого сравнения в сортировке.


это вряд ли питонический язык, хотя он решает задачу (отказ от ответственности: не тестировал код).
Адриано Вароли Пьяцца,

Это решение не исключает каталоги из списка.
Константин

@Constantin: это правда, но быстрый [... if stat.S_ISREG (x)] справится с этим.
Грег Хьюгилл,

16

Без смены каталога:

import os    

path = '/path/to/files/'
name_list = os.listdir(path)
full_list = [os.path.join(path,i) for i in name_list]
time_sorted_list = sorted(full_list, key=os.path.getmtime)

print time_sorted_list

# if you want just the filenames sorted, simply remove the dir from each
sorted_filename_list = [ os.path.basename(i) for i in time_sorted_list]
print sorted_filename_list


11

Вот мой ответ с использованием glob без фильтра, если вы хотите читать файлы с определенным расширением в порядке даты (Python 3).

dataset_path='/mydir/'   
files = glob.glob(dataset_path+"/morepath/*.extension")   
files.sort(key=os.path.getmtime)

5
# *** the shortest and best way ***
# getmtime --> sort by modified time
# getctime --> sort by created time

import glob,os

lst_files = glob.glob("*.txt")
lst_files.sort(key=os.path.getmtime)
print("\n".join(lst_files))

пожалуйста, предоставьте контекст
Клэр

«лучший» субъективен. Ваш ответ был бы лучше, если бы вы объяснили, почему вы думаете, что это лучший способ.
Bryan Oakley

Если вы хотите «лучшего», вы, конечно, не используйте glob, так как он очень медленный.
user136036

4
sorted(filter(os.path.isfile, os.listdir('.')), 
    key=lambda p: os.stat(p).st_mtime)

Вы можете использовать os.walk('.').next()[-1]вместо фильтрации с os.path.isfile, но это оставляет мертвые символические ссылки в списке и os.statне работает с ними.


4
from pathlib import Path
import os

sorted(Path('./').iterdir(), key=lambda t: t.stat().st_mtime)

или

sorted(Path('./').iterdir(), key=os.path.getmtime)

или

sorted(os.scandir('./'), key=lambda t: t.stat().st_mtime)

где m время - модифицированное время.


1

это основной шаг для обучения:

import os, stat, sys
import time

dirpath = sys.argv[1] if len(sys.argv) == 2 else r'.'

listdir = os.listdir(dirpath)

for i in listdir:
    os.chdir(dirpath)
    data_001 = os.path.realpath(i)
    listdir_stat1 = os.stat(data_001)
    listdir_stat2 = ((os.stat(data_001), data_001))
    print time.ctime(listdir_stat1.st_ctime), data_001

1

Ответ Алекса Ковентри вызовет исключение, если файл является символической ссылкой на несуществующий файл, следующий код исправляет этот ответ:

import time
import datetime
sorted(filter(os.path.isfile, os.listdir('.')), 
    key=lambda p: os.path.exists(p) and os.stat(p).st_mtime or time.mktime(datetime.now().timetuple())

Когда файл не существует, используется now (), и символическая ссылка будет находиться в самом конце списка.


0

Вот пара простых строк, которые ищут расширение, а также предоставляют возможность сортировки

def get_sorted_files(src_dir, regex_ext='*', sort_reverse=False): 
    files_to_evaluate = [os.path.join(src_dir, f) for f in os.listdir(src_dir) if re.search(r'.*\.({})$'.format(regex_ext), f)]
    files_to_evaluate.sort(key=os.path.getmtime, reverse=sort_reverse)
    return files_to_evaluate

0

Для полноты os.scandir(в 2 раза быстрее pathlib):

import os
sorted(os.scandir('/tmp/test'), key=lambda d: d.stat().st_mtime)

0

Это была моя версия:

import os

folder_path = r'D:\Movies\extra\new\dramas' # your path
os.chdir(folder_path) # make the path active
x = sorted(os.listdir(), key=os.path.getctime)  # sorted using creation time

folder = 0

for folder in range(len(x)):
    print(x[folder]) # print all the foldername inside the folder_path
    folder = +1

В моем коде файлы отсортированы от самых старых до самых новых. Чтобы сначала получить новейшие имена файлов или папок, вам нужно добавить reverse = True в список файлов (в моем случае это было x). итак, x = sorted (os.listdir (), key = os.path.getctime, reverse = True)
haqrafiul

-6

Возможно, вам стоит использовать команды оболочки. В Unix / Linux команда find piped with sort, вероятно, сможет делать то, что вы хотите.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.