Comment obtenir une liste de répertoires triée par date de création en python?

129

Quelle est la meilleure façon d'obtenir une liste de tous les fichiers d'un répertoire, triés par date [créé | modifié], en utilisant python, sur une machine Windows?

Liza
la source

Réponses:

79

Mise à jour : pour trier dirpathles entrées par date de modification dans Python 3:

import os
from pathlib import Path

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

(mettez la réponse de @ Pygirl ici pour une plus grande visibilité)

Si vous avez déjà une liste de noms de fichiers files, alors pour la trier sur place par heure de création sous Windows:

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

La liste des fichiers que vous pourriez obtenir, par exemple, en utilisant globcomme indiqué dans la réponse de @ Jay .


ancienne réponse Voici une version plus détaillée de @Greg Hewgillla réponse de . C'est la plus conforme aux exigences de la question. Il fait une distinction entre les dates de création et de modification (au moins sous 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)

Exemple:

$ python stat_creation_date.py
Thu Feb 11 13:31:07 2009 stat_creation_date.py
jfs
la source
1
Cela a parfaitement fonctionné. J'essaye de comparer deux répertoires cdate les uns avec les autres. Existe-t-il un moyen de comparer les secondes entre les deux cdates?
Federer
@malcmcmul: cdateest un nombre flottant de secondes depuis Epoch.
jfs
4
Cela fonctionne, mais la solution la plus succincte est à stackoverflow.com/a/4500607/68534
jmoz
@jmoz: voulez-vous dire comme ça . La solution que vous liez est fausse: elle ne filtre pas les fichiers normaux. Remarque: ma solution appelle statune fois par entrée de répertoire.
jfs
Pardonnez-moi, le lien fourni par Sabastian est encore plus succinct! Je vous remercie.
jmoz
148

J'ai fait cela dans le passé pour un script Python afin de déterminer les derniers fichiers mis à jour dans un répertoire:

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

Cela devrait faire ce que vous recherchez en fonction du fichier mtime.

EDIT : Notez que vous pouvez également utiliser os.listdir () à la place de glob.glob () si vous le souhaitez - la raison pour laquelle j'ai utilisé glob dans mon code d'origine était que je voulais utiliser glob pour rechercher uniquement des fichiers avec un ensemble particulier des extensions de fichiers, auxquelles glob () était mieux adapté. Pour utiliser listdir, voici à quoi cela ressemblerait:

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))
Geai
la source
glob () est bien, mais gardez à l'esprit qu'il ignore les fichiers commençant par un point. * Les systèmes nix traitent ces fichiers comme cachés (les omettant ainsi des listes), mais sous Windows, ce sont des fichiers normaux.
efotinis
Ces solutions n'excluent pas les répertoires de la liste.
Constantin
Votre solution os.listdir ne contient pas 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
files.sort(key=lambda fn: os.path.getmtime(os.path.join(search_dir, fn)))
jfs
22
Un simple files.sort(key=os.path.getmtime)devrait fonctionner (sans lambda).
jfs
31

Il existe une os.path.getmtimefonction qui donne le nombre de secondes depuis l'époque et devrait être plus rapide que os.stat.

import os 

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

Voici ma version:

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

Tout d'abord, nous construisons une liste des noms de fichiers. isfile () est utilisé pour sauter les répertoires; il peut être omis si des répertoires doivent être inclus. Ensuite, nous trions la liste sur place, en utilisant la date de modification comme clé.

efotinis
la source
Il l'a trié du plus ancien au plus récent. Lorsque je voulais les 5 derniers fichiers, je devais faire ce qui suita[-5:]
Daniel Butler
20

Voici un one-liner:

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

Cela appelle os.listdir () pour obtenir une liste des noms de fichiers, puis appelle os.stat () pour chacun d'eux pour obtenir l'heure de création, puis trie par rapport à l'heure de création.

Notez que cette méthode n'appelle os.stat () qu'une seule fois pour chaque fichier, ce qui sera plus efficace que de l'appeler pour chaque comparaison d'un tri.

Greg Hewgill
la source
c'est à peine pythonique, bien que cela résout le travail (avertissement: n'a pas testé le code).
Adriano Varoli Piazza
Cette solution n'exclut pas les répertoires de la liste.
Constantin
@Constantin: c'est vrai, mais un rapide [... if stat.S_ISREG (x)] le gérerait.
Greg Hewgill
16

Sans changer de répertoire:

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
la source
12

En python 3.5+

from pathlib import Path
sorted(Path('.').iterdir(), key=lambda f: f.stat().st_mtime)
ignorant
la source
3
pour la date de création, utilisez f.stat().st_ctimeplutôt.
alanjds
11

Voici ma réponse en utilisant glob sans filtre si vous souhaitez lire des fichiers avec une certaine extension par ordre de date (Python 3).

dataset_path='/mydir/'   
files = glob.glob(dataset_path+"/morepath/*.extension")   
files.sort(key=os.path.getmtime)
dinos66
la source
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
la source
veuillez fournir le contexte
Claire
«meilleur» est subjectif. Votre réponse serait meilleure si vous expliquiez pourquoi vous pensez que c'est le meilleur moyen.
Bryan Oakley
Si vous voulez "le meilleur", vous n'utilisez certainement pas glob, car c'est vraiment lent.
user136036
4
sorted(filter(os.path.isfile, os.listdir('.')), 
    key=lambda p: os.stat(p).st_mtime)

Vous pouvez utiliser os.walk('.').next()[-1]au lieu de filtrer avec os.path.isfile, mais cela laisse des liens symboliques morts dans la liste et os.statéchouera sur eux.

Alex Coventry
la source
4
from pathlib import Path
import os

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

ou

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

ou

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

où m temps est le temps modifié.

Pygirl
la source
1

c'est une étape de base pour apprendre:

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
la source
1

La réponse d'Alex Coventry produira une exception si le fichier est un lien symbolique vers un fichier inexistant, le code suivant corrige cette réponse:

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

Lorsque le fichier n'existe pas, now () est utilisé, et le lien symbolique ira à la toute fin de la liste.

Paolo Benvenuto
la source
0

Voici quelques lignes simples qui recherchent une extension et fournissent une option de tri

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
la source
0

Pour être complet avec os.scandir(2x plus rapide pathlib):

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

C'était ma version:

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
la source
Dans mon code, les fichiers sont triés du plus ancien au plus récent. Pour obtenir en premier les noms de fichiers ou dossiers les plus récents, vous devez ajouter reverse = True dans la liste des fichiers (dans mon cas, c'était x). so, x = sorted (os.listdir (), key = os.path.getctime, reverse = True)
haqrafiul
-6

Vous devriez peut-être utiliser des commandes shell. Sous Unix / Linux, find piped with sort sera probablement capable de faire ce que vous voulez.

stephanea
la source