Jak uzyskać listę katalogów posortowaną według daty utworzenia w Pythonie?


129

Jaki jest najlepszy sposób uzyskania listy wszystkich plików w katalogu, posortowanych według daty [utworzono | zmodyfikowano], używając języka Python, na komputerze z systemem Windows?

Odpowiedzi:


79

Aktualizacja : aby posortować dirpathwpisy według daty modyfikacji w Pythonie 3:

import os
from pathlib import Path

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

(wstaw odpowiedź @ Pygirl tutaj, aby uzyskać lepszą widoczność)

Jeśli masz już listę nazw plików files, posortuj ją według czasu utworzenia w systemie Windows:

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

Lista plików, które możesz uzyskać, na przykład, używając, globjak pokazano w odpowiedzi @ Jaya .


stara odpowiedź Oto bardziej szczegółowa wersja @Greg Hewgillodpowiedzi . Jest to najbardziej zgodne z wymaganiami pytania. Wprowadza rozróżnienie między datami utworzenia i modyfikacji (przynajmniej w systemie 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)

Przykład:

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

1
To działało doskonale. Próbuję porównać ze sobą dwa katalogi cdate. Czy jest sposób na porównanie sekund między dwoma płytami CD?
Federer

@malcmcmul: cdateto zmiennoprzecinkowa liczba sekund od epoki.
jfs

4
To działa, ale najbardziej zwięzłe rozwiązanie znajduje się na stackoverflow.com/a/4500607/68534
jmoz

@jmoz: czy masz na myśli to . Rozwiązanie, do którego odsyłasz, jest nieprawidłowe: nie filtruje zwykłych plików. Uwaga: moje rozwiązanie wywołuje statjeden raz w każdym katalogu.
jfs

Wybaczcie, link podany przez Sabastiana jest jeszcze bardziej zwięzły! Dziękuję Ci.
jmoz

148

Robiłem to w przeszłości dla skryptu Pythona do określenia ostatnich zaktualizowanych plików w katalogu:

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

To powinno zrobić to, czego szukasz, na podstawie pliku mtime.

EDYCJA : Zauważ, że możesz również użyć os.listdir () zamiast glob.glob () w razie potrzeby - powodem, dla którego użyłem glob w moim oryginalnym kodzie, było to, że chciałem użyć glob do wyszukiwania tylko plików z określonym zestawem rozszerzeń plików, do których lepiej pasowała funkcja glob (). Aby użyć listdir, oto jak by to wyglądało:

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 () jest fajne, ale pamiętaj, że pomija pliki zaczynające się od kropki. Systemy * nix traktują takie pliki jako ukryte (pomijając je w ten sposób na liście), ale w systemie Windows są to zwykłe pliki.
efotinis

Te rozwiązania nie wykluczają książek z listy.
Constantin

W rozwiązaniu os.listdir brakuje pliku 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
Zwykły files.sort(key=os.path.getmtime)powinien działać (bez lambda).
jfs

31

Istnieje os.path.getmtimefunkcja, która podaje liczbę sekund od epoki i powinna być szybsza niż os.stat.

import os 

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

23

Oto moja wersja:

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

Najpierw tworzymy listę nazw plików. isfile () służy do pomijania katalogów; można go pominąć, jeśli mają być uwzględnione katalogi. Następnie sortujemy listę lokalnie, używając daty modyfikacji jako klucza.


Posortował je od najstarszego do najnowszego. Kiedy chciałem mieć 5 najnowszych plików, musiałem zrobić co następujea[-5:]
Daniel Butler

20

Oto jedna linijka:

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

To wywołuje os.listdir (), aby uzyskać listę nazw plików, a następnie wywołuje os.stat () dla każdego z nich, aby uzyskać czas utworzenia, a następnie sortuje w odniesieniu do czasu utworzenia.

Zauważ, że ta metoda wywołuje os.stat () tylko raz dla każdego pliku, co będzie bardziej wydajne niż wywoływanie jej dla każdego porównania w sortowaniu.


to nie jest Pythonowe, chociaż rozwiązuje zadanie (zastrzeżenie: nie testowałem kodu).
Adriano Varoli Piazza

To rozwiązanie nie wyklucza książek z listy.
Constantin,

@Constantin: to prawda, ale szybkie [... jeśli stat.S_ISREG (x)] poradzi sobie z tym.
Greg Hewgill

16

Bez zmiany katalogu:

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

12

W Pythonie 3.5+

from pathlib import Path
sorted(Path('.').iterdir(), key=lambda f: f.stat().st_mtime)

3
f.stat().st_ctimezamiast daty utworzenia użyj .
alanjds

11

Oto moja odpowiedź przy użyciu globu bez filtra, jeśli chcesz czytać pliki z określonym rozszerzeniem w kolejności dat (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))

proszę podać kontekst
Claire,

„najlepsze” jest subiektywne. Twoja odpowiedź byłaby lepsza, gdybyś wyjaśnił, dlaczego uważasz, że to najlepszy sposób.
Bryan Oakley

Jeśli chcesz „najlepszego”, na pewno nie używasz globu, ponieważ jest bardzo wolny.
user136036

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

Możesz użyć os.walk('.').next()[-1]zamiast filtrowania z os.path.isfile, ale to pozostawia martwe dowiązania symboliczne na liście i os.statzawiedzie na nich.


4
from pathlib import Path
import os

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

lub

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

lub

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

gdzie m czas jest czasem zmodyfikowanym.


1

to jest podstawowy krok do nauki:

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

Odpowiedź Alexa Coventry'ego spowoduje wyjątek, jeśli plik jest dowiązaniem symbolicznym do nieistniejącego pliku, poniższy kod poprawia tę odpowiedź:

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

Gdy plik nie istnieje, używana jest funkcja now (), a dowiązanie symboliczne zostanie umieszczone na samym końcu listy.


0

Oto kilka prostych linii, które szukają rozszerzenia, a także zapewniają opcję sortowania

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

Aby uzyskać kompletność z os.scandir(2x szybciej pathlib):

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

0

To była moja wersja:

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

W moim kodzie pliki są sortowane od najstarszych do najnowszych. Aby najpierw pobrać najnowsze nazwy plików lub folderów, musisz dodać reverse = True na liście plików (w moim przypadku było to x). tak, x = sortowane (os.listdir (), key = os.path.getctime, reverse = True)
haqrafiul

-6

Może powinieneś użyć poleceń powłoki. W Unix / Linux, find piped with sort prawdopodobnie będzie w stanie zrobić to, co chcesz.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.