Как получить список каталогов, отсортированный по дате создания в 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
JFS
источник
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)
Gypaetus
источник
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 () используется для пропуска каталогов; его можно не указывать, если необходимо включить каталоги. Затем мы сортируем список на месте, используя дату изменения в качестве ключа.

efotinis
источник
Оно отсортировано от самых старых к самым новым. Когда мне 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
Nic
источник
12

В Python 3.5+

from pathlib import Path
sorted(Path('.').iterdir(), key=lambda f: f.stat().st_mtime)
невежественный
источник
3
f.stat().st_ctimeвместо даты создания используйте .
alanjds 07
11

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

dataset_path='/mydir/'   
files = glob.glob(dataset_path+"/morepath/*.extension")   
files.sort(key=os.path.getmtime)
dinos66
источник
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 время - модифицированное время.

Pygirl
источник
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
cumulus_13
источник
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
TXN_747
источник
0

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

import os
sorted(os.scandir('/tmp/test'), key=lambda d: d.stat().st_mtime)
n1nj4
источник
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
haqrafiul
источник
В моем коде файлы отсортированы от самых старых до самых новых. Чтобы сначала получить новейшие имена файлов или папок, вам нужно добавить reverse = True в список файлов (в моем случае это было x). итак, x = sorted (os.listdir (), key = os.path.getctime, reverse = True)
haqrafiul
-6

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

stephanea
источник