Python'da oluşturulma tarihine göre sıralanmış bir dizin listesini nasıl elde edersiniz?


129

Tarihe göre sıralanmış bir dizindeki tüm dosyaların listesini almanın en iyi yolu nedir [oluşturuldu | değiştirildi], python kullanarak, bir Windows makinesinde?

Yanıtlar:


79

Güncelleme : dirpathgirişlerini Python 3'te değişiklik tarihine göre sıralamak için :

import os
from pathlib import Path

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

( Daha fazla görünürlük için @ Pygirl'ın cevabını buraya koyun )

Zaten bir dosya adları listeniz varsa files, Windows'ta oluşturma zamanına göre yerinde sıralamak için:

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

Örneğin @ Jay'in cevabındaglob gösterildiği gibi kullanarak alabileceğiniz dosyaların listesi .


Eski cevap İşte sürümüne ayrıntılı bir fazlası var @Greg Hewgillcevabını . Soru gereksinimlerine en uygun olanıdır. Oluşturma ve değiştirme tarihleri ​​arasında bir ayrım yapar (en azından Windows'ta).

#!/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)

Misal:

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

1
Bu mükemmel çalıştı. İki dizini cdate ile karşılaştırmaya çalışıyorum. İki cdate arasındaki saniyeleri karşılaştırmanın bir yolu var mı?
Federer

@malcmcmul: Epoch'tan cdatebu yana kayan saniye sayısıdır.
jfs

4
Bu işe yarıyor ancak en özlü çözüm stackoverflow.com/a/4500607/68534
jmoz

@jmoz: Eğer gibi demek bu . Bağladığınız çözüm yanlış: normal dosyaları filtrelemez. Not: benim çözümüm stather dizin girişi için bir kez çağırıyor.
jfs

Bağışlayın beni, Sabastian tarafından sağlanan bağlantı daha da kısa! Teşekkür ederim.
jmoz

148

Bunu geçmişte bir Python betiği için bir dizindeki son güncellenen dosyaları belirlemek için yaptım:

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

Bu, dosya mtime'ına göre aradığınız şeyi yapmalıdır.

DÜZENLEME : İsterseniz glob.glob () yerine os.listdir () de kullanabileceğinizi unutmayın - orijinal kodumda glob kullanmamın nedeni, glob'u yalnızca belirli bir kümeye sahip dosyaları aramak için kullanmak istememdi glob () 'un daha uygun olduğu dosya uzantıları. Listdir kullanmak için şöyle görünecektir:

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 () iyidir, ancak bir noktayla başlayan dosyaları atladığını unutmayın. * nix sistemleri bu tür dosyaları gizli olarak ele alır (bu nedenle listelerden çıkarır), ancak Windows'ta bunlar normal dosyalardır.
efotinis

Bu çözümler dizinleri listeden hariç tutmaz.
Constantin

Os.listdir çözümünüzde 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
Bir basit files.sort(key=os.path.getmtime)(olmadan lambda) çalışmalıdır .
jfs

31

os.path.getmtimeDönemden beri geçen saniye sayısını veren ve daha hızlı olması gereken bir fonksiyon var os.stat.

import os 

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

23

İşte benim versiyonum:

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

İlk olarak, dosya adlarının bir listesini oluşturuyoruz. isfile () dizinleri atlamak için kullanılır; dizinlerin dahil edilmesi gerekiyorsa ihmal edilebilir. Ardından, anahtar olarak değiştirme tarihini kullanarak listeyi yerinde sıralarız.


Önce en eskiden en yeniye doğru sıraladı. En yeni 5 dosyayı istediğimde aşağıdakileri yapmak zorunda kaldıma[-5:]
Daniel Butler

20

İşte tek satırlık:

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

Bu, dosya adlarının bir listesini almak için os.listdir () 'i çağırır, ardından her biri için oluşturma zamanını almak için os.stat ()' ı çağırır, ardından oluşturma zamanına göre sıralar.

Bu yöntemin os.stat () işlevini her dosya için yalnızca bir kez çağırdığını unutmayın; bu, bir sıralamadaki her karşılaştırma için onu çağırmaktan daha verimli olacaktır.


Bu, işi çözmesine rağmen pek pitonik değildir (sorumluluk reddi: kodu test etmedi).
Adriano Varoli Piazza

Bu çözüm dizinleri listeden hariç tutmaz.
Constantin

@Constantin: bu doğru, ancak hızlı bir [... eğer stat.S_ISREG (x)] bunu halledebilir.
Greg Hewgill

16

Dizini değiştirmeden:

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

Python 3.5+

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

3
oluşturma tarihi için f.stat().st_ctimebunun yerine kullanın.
alanjds

11

Belirli bir uzantıya sahip dosyaları tarih sırasına göre (Python 3) okumak istiyorsanız, filtresiz glob kullanarak cevabım burada.

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

lütfen bağlamı
Claire

"en iyi" özneldir. Cevabınız neden en iyi yol olduğunu düşündüğünüzü açıklarsanız daha iyi olur.
Bryan Oakley

"En iyiyi" istiyorsanız, gerçekten yavaş olduğu için kesinlikle glob kullanmazsınız.
user136036

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

İle os.walk('.').next()[-1]filtreleme yerine kullanabilirsiniz os.path.isfile, ancak bu, listede ölü sembolik bağlar bırakır ve os.statbunlarda başarısız olur.


4
from pathlib import Path
import os

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

veya

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

veya

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

m zamanı, değiştirilme zamanıdır.


1

bu öğrenmek için temel bir adımdır:

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

Alex Coventry'nin cevabı, eğer dosya var olmayan bir dosyaya bir sembolik bağ ise bir istisna oluşturacaktır, aşağıdaki kod bu cevabı düzeltir:

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

Dosya mevcut olmadığında, şimdi () kullanılır ve sembolik bağlantı listenin en sonuna gider.


0

Burada, uzantı arayan ve bir sıralama seçeneği sunan basit bir çift satır var.

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

os.scandirTamlık için (2 kat daha hızlı pathlib):

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

0

Bu benim versiyonumdu:

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

Benim kodumda dosyalar en eskiden en yeniye sıralanır. Önce en yeni dosya adlarını veya klasörleri almak için dosya listesine reverse = True eklemeniz gerekir (benim durumumda x idi). yani, x = sıralanmış (os.listdir (), anahtar = os.path.getctime, reverse = True)
haqrafiul

-6

Belki kabuk komutlarını kullanmalısın. Unix / Linux'ta, sort ile borulu bulun, muhtemelen istediğinizi yapacaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.