¿Cómo se obtiene un listado de directorio ordenado por fecha de creación en Python?

129

¿Cuál es la mejor manera de obtener una lista de todos los archivos en un directorio, ordenados por fecha [creado | modificado], utilizando Python, en una máquina con Windows?

Liza
fuente

Respuestas:

79

Actualización : para ordenar dirpathlas entradas por fecha de modificación en Python 3:

import os
from pathlib import Path

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

( Pon la respuesta de @ Pygirl aquí para una mayor visibilidad)

Si ya tiene una lista de nombres de archivo files, entonces ordénela por hora de creación en Windows:

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

La lista de archivos que puede obtener, por ejemplo, utilizando globcomo se muestra en la respuesta de @ Jay .


respuesta anterior Aquí hay una versión más detallada de @Greg Hewgillla respuesta de . Es el más conforme a los requisitos de la pregunta. Hace una distinción entre las fechas de creación y modificación (al menos en 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)

Ejemplo:

$ python stat_creation_date.py
Thu Feb 11 13:31:07 2009 stat_creation_date.py
jfs
fuente
1
Esto funcionó perfectamente. Estoy tratando de comparar dos directorios cdate entre sí. ¿Hay alguna manera de comparar los segundos entre las dos fechas?
Federer
@malcmcmul: cdatees un número flotante de segundos desde Epoch.
jfs el
44
Esto funciona, pero la solución más sucinta está en stackoverflow.com/a/4500607/68534
jmoz
@ jmoz: ¿te refieres a esto ? La solución que ha vinculado es incorrecta: no filtra los archivos normales. Nota: mi solución llama statuna vez por dir.entry.
jfs
Perdóname, ¡el enlace proporcionado por Sabastian es aún más sucinto! Gracias.
jmoz
148

He hecho esto en el pasado para un script de Python para determinar los últimos archivos actualizados en un directorio:

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))

Eso debería hacer lo que estás buscando en función del archivo mtime.

EDITAR : tenga en cuenta que también puede usar os.listdir () en lugar de glob.glob () si lo deseaba; la razón por la que usé glob en mi código original fue que quería usar glob para buscar solo archivos con un conjunto particular de extensiones de archivo, que glob () se adapta mejor a. Para usar listdir, así es como se vería:

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))
Arrendajo
fuente
glob () es bueno, pero tenga en cuenta que omite los archivos que comienzan con un punto. * los sistemas nix tratan dichos archivos como ocultos (por lo tanto, los omiten de los listados), pero en Windows son archivos normales.
efotinis
Estas soluciones no excluyen directorios de la lista.
Constantin
A su solución os.listdir le falta 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))))
Peter Hoffmann el
files.sort(key=lambda fn: os.path.getmtime(os.path.join(search_dir, fn)))
jfs
22
Un mero files.sort(key=os.path.getmtime)debería funcionar (sin lambda).
jfs
31

Hay una os.path.getmtimefunción que da la cantidad de segundos desde la época y debería ser más rápida que os.stat.

import os 

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

Aquí está mi versión:

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

Primero, creamos una lista de los nombres de los archivos. isfile () se usa para omitir directorios; se puede omitir si se deben incluir directorios. Luego, clasificamos la lista en el lugar, usando la fecha de modificación como clave.

efotinis
fuente
Lo clasificó de más antiguo a más nuevo. Cuando quería los 5 archivos más nuevos, tenía que hacer lo siguientea[-5:]
Daniel Butler
20

Aquí hay una frase:

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)])

Esto llama a os.listdir () para obtener una lista de los nombres de archivo, luego llama a os.stat () para que cada uno obtenga el tiempo de creación, luego se compara con el tiempo de creación.

Tenga en cuenta que este método solo llama a os.stat () una vez para cada archivo, lo que será más eficiente que llamarlo para cada comparación en una especie.

Greg Hewgill
fuente
eso no es pitónico, aunque resuelve el trabajo (descargo de responsabilidad: no probó el código).
Adriano Varoli Piazza
Esta solución no excluye directorios de la lista.
Constantin
@Constantin: eso es cierto, pero un rápido [... si stat.S_ISREG (x)] manejaría eso.
Greg Hewgill
16

Sin cambiar de directorio:

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
fuente
12

En python 3.5+

from pathlib import Path
sorted(Path('.').iterdir(), key=lambda f: f.stat().st_mtime)
ignorante
fuente
3
para la fecha de creación, use f.stat().st_ctimeen su lugar.
alanjds
11

Aquí está mi respuesta usando glob sin filtro si desea leer archivos con una cierta extensión en orden de fecha (Python 3).

dataset_path='/mydir/'   
files = glob.glob(dataset_path+"/morepath/*.extension")   
files.sort(key=os.path.getmtime)
dinos66
fuente
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))
Arash
fuente
proporcione contexto
Claire
"mejor" es subjetivo. Su respuesta sería mejor si explicara por qué cree que es la mejor manera.
Bryan Oakley
Si quiere "lo mejor", ciertamente no usa glob, ya que es realmente lento.
usuario136036
4
sorted(filter(os.path.isfile, os.listdir('.')), 
    key=lambda p: os.stat(p).st_mtime)

Podría usar en os.walk('.').next()[-1]lugar de filtrar con os.path.isfile, pero eso deja enlaces simbólicos muertos en la lista y os.statfallará en ellos.

Alex Coventry
fuente
4
from pathlib import Path
import os

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

o

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

o

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

donde m tiempo es tiempo modificado.

Pygirl
fuente
1

Este es un paso básico para aprender:

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
fuente
1

La respuesta de Alex Coventry producirá una excepción si el archivo es un enlace simbólico a un archivo inexistente, el siguiente código corrige esa respuesta:

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())

Cuando el archivo no existe, se usa now (), y el enlace simbólico irá al final de la lista.

Paolo Benvenuto
fuente
0

Aquí hay un par de líneas simples que buscan la extensión y proporcionan una opción de clasificación

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
fuente
0

Para completar con os.scandir(2 veces más rápido pathlib):

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

Esta fue mi versión:

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
fuente
En mi código, los archivos se ordenan del más antiguo al más nuevo. Para obtener primero los nombres de archivo o carpetas más nuevos, debe agregar reverse = True en la lista de archivos (en mi caso, era x). entonces, x = ordenado (os.listdir (), clave = os.path.getctime, reverse = True)
haqrafiul
-6

Tal vez deberías usar comandos de shell. En Unix / Linux, find piped with sort probablemente podrá hacer lo que quiera.

stephanea
fuente