Domanda

Qual è il modo migliore per ottenere un elenco di tutti i file in una directory, ordinati per data [creato | modificato], usando Python, su una macchina Windows?

È stato utile?

Soluzione

Ecco una versione più dettagliata di La risposta di @Greg Hewgill . È il più conforme ai requisiti della domanda. Fa una distinzione tra le date di creazione e modifica (almeno su 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)

Esempio:

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

Altri suggerimenti

L'ho fatto in passato per uno script Python per determinare gli ultimi file aggiornati in una directory:

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 = filter(os.path.isfile, glob.glob(search_dir + "*"))
files.sort(key=lambda x: os.path.getmtime(x))

Questo dovrebbe fare quello che stai cercando in base al file mtime.

MODIFICA : Nota che puoi anche usare os.listdir () al posto di glob.glob () se lo desideri - il motivo per cui ho usato glob nel mio codice originale era che volevo usare glob per cercare solo file con una particolare serie di estensioni di file, a cui glob () era più adatto. Per usare listdir ecco come sarebbe:

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

Ecco la mia versione:

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

Innanzitutto, costruiamo un elenco dei nomi dei file. isfile () è usato per saltare le directory; può essere omesso se si devono includere le directory. Quindi, ordiniamo l'elenco sul posto, usando la data di modifica come chiave.

Esiste una funzione os.path.getmtime che fornisce il numero di secondi dall'epoca e dovrebbe essere più veloce di os.stat .

import os 

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

Ecco una riga:

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

Questo chiama os.listdir () per ottenere un elenco dei nomi dei file, quindi chiama os.stat () per ognuno per ottenere il tempo di creazione, quindi ordina in base al tempo di creazione.

Nota che questo metodo chiama os.stat () solo una volta per ogni file, il che sarà più efficiente che chiamarlo per ogni confronto in un ordinamento.

Senza cambiare directory:

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

Ecco la mia risposta usando glob senza filtro se vuoi leggere i file con una certa estensione in ordine di data (Python 3).

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

In python 3.5+

from pathlib import Path
sorted(Path('.').iterdir(), key=lambda f: f.stat().st_mtime)
sorted(filter(os.path.isfile, os.listdir('.')), 
    key=lambda p: os.stat(p).st_mtime)

Puoi usare os.walk ('.'). next () [- 1] invece di filtrare con os.path.isfile , ma questo lascia morto i collegamenti simbolici nell'elenco e os.stat falliranno su di essi.

questo è un passo fondamentale per imparare:

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

La risposta di Alex Coventry produrrà un'eccezione se il file è un collegamento simbolico a un file inesistente, il seguente codice corregge quella risposta:

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

Quando il file non esiste, viene utilizzato now () e il collegamento simbolico andrà alla fine dell'elenco.

Ecco una semplice coppia di righe che cerca l'estensione e fornisce un'opzione di ordinamento

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

Forse dovresti usare i comandi di shell. In Unix / Linux, trovare il piping con sort sarà probabilmente in grado di fare quello che vuoi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top