Bagaimana Anda mendapatkan daftar direktori yang diurutkan berdasarkan tanggal pembuatan dalam python?

129

Apa cara terbaik untuk mendapatkan daftar semua file dalam direktori, diurutkan berdasarkan tanggal [dibuat | dimodifikasi], menggunakan python, pada mesin windows?

Liza
sumber

Jawaban:

79

Perbarui : untuk mengurutkan dirpathentri berdasarkan tanggal modifikasi dengan Python 3:

import os
from pathlib import Path

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

(letakkan jawaban @ Pygirl di sini untuk visibilitas lebih besar)

Jika Anda sudah memiliki daftar nama file files, maka untuk mengurutkannya berdasarkan waktu pembuatan pada Windows:

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

Daftar file yang bisa Anda peroleh, misalnya, menggunakan globseperti yang ditunjukkan pada jawaban @ Jay .


Jawabannya tua Berikut adalah lebih verbose versi @Greg Hewgill's jawaban . Ini adalah yang paling sesuai dengan persyaratan pertanyaan. Itu membuat perbedaan antara tanggal pembuatan dan modifikasi (setidaknya pada 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)

Contoh:

$ python stat_creation_date.py
Thu Feb 11 13:31:07 2009 stat_creation_date.py
jfs
sumber
1
Ini bekerja dengan sempurna. Saya mencoba membandingkan dua direktori cdate satu sama lain. Apakah ada cara untuk membandingkan detik antara dua cdate?
Federer
@malcmcmul: cdateadalah jumlah float detik sejak Epoch.
jfs
4
Ini berfungsi tetapi solusi yang paling ringkas adalah di stackoverflow.com/a/4500607/68534
jmoz
@jmoz: maksudmu seperti ini . Solusi yang Anda tautkan salah: tidak menyaring file biasa. Catatan: solusi saya memanggil statsekali per dir.entry.
jfs
Maafkan saya, tautan yang disediakan oleh Sabastian bahkan lebih ringkas! Terima kasih.
jmoz
148

Saya telah melakukan ini di masa lalu untuk skrip Python untuk menentukan file yang terakhir diperbarui dalam direktori:

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

Itu harus melakukan apa yang Anda cari berdasarkan file mtime.

EDIT : Perhatikan bahwa Anda juga dapat menggunakan os.listdir () sebagai ganti glob.glob () jika diinginkan - alasan saya menggunakan glob dalam kode asli saya adalah bahwa saya ingin menggunakan glob untuk hanya mencari file dengan set tertentu ekstensi file, yang glob () lebih cocok untuk. Untuk menggunakan listdir, inilah tampilannya:

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))
Jay
sumber
glob () bagus, tetapi perlu diingat bahwa ia melompati file yang dimulai dengan titik. * Sistem nix memperlakukan file seperti itu sebagai tersembunyi (sehingga menghilangkannya dari daftar), tetapi di Windows mereka adalah file normal.
efotinis
Solusi ini tidak mengecualikan dir dari daftar.
Constantin
Solusi os.listdir Anda tidak memiliki 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
Seorang belaka files.sort(key=os.path.getmtime)harus bekerja (tanpa lambda).
jfs
31

Ada os.path.getmtimefungsi yang memberikan jumlah detik sejak zaman dan harus lebih cepat dari os.stat.

import os 

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

Ini versi saya:

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

Pertama, kami membuat daftar nama file. isfile () digunakan untuk melewati direktori; dapat dihilangkan jika direktori harus dimasukkan. Kemudian, kami mengurutkan daftar di tempat, menggunakan tanggal modifikasi sebagai kuncinya.

efotinis
sumber
Ini mengurutkannya dari yang terlama ke yang terbaru. Ketika saya ingin 5 file terbaru saya harus melakukan yang berikuta[-5:]
Daniel Butler
20

Inilah satu kalimat:

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

Ini memanggil os.listdir () untuk mendapatkan daftar nama file, lalu memanggil os.stat () untuk masing-masing nama untuk mendapatkan waktu pembuatan, kemudian mengurutkannya terhadap waktu pembuatan.

Perhatikan bahwa metode ini hanya memanggil os.stat () satu kali untuk setiap file, yang akan lebih efisien daripada memanggilnya untuk setiap perbandingan dalam bentuk.

Greg Hewgill
sumber
itu hampir tidak pythonic, meskipun itu menyelesaikan pekerjaan (penafian: tidak menguji kode).
Adriano Varoli Piazza
Solusi ini tidak mengecualikan dir dari daftar.
Constantin
@Constantin: itu benar, tetapi [... jika stat.S_ISREG (x)] cepat akan mengatasinya.
Greg Hewgill
16

Tanpa mengubah direktori:

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

Dalam python 3.5+

from pathlib import Path
sorted(Path('.').iterdir(), key=lambda f: f.stat().st_mtime)
bodoh
sumber
3
untuk tanggal pembuatan, gunakan f.stat().st_ctimesaja.
alanjds
11

Inilah jawaban saya menggunakan glob tanpa filter jika Anda ingin membaca file dengan ekstensi tertentu dalam urutan tanggal (Python 3).

dataset_path='/mydir/'   
files = glob.glob(dataset_path+"/morepath/*.extension")   
files.sort(key=os.path.getmtime)
dinos66
sumber
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
sumber
tolong berikan konteks
Claire
"terbaik" adalah subyektif. Jawaban Anda akan lebih baik jika Anda menjelaskan mengapa menurut Anda itu cara terbaik.
Bryan Oakley
Jika Anda menginginkan "yang terbaik", Anda tentu tidak menggunakan glob, karena ini sangat lambat.
user136036
4
sorted(filter(os.path.isfile, os.listdir('.')), 
    key=lambda p: os.stat(p).st_mtime)

Anda bisa menggunakan os.walk('.').next()[-1]alih-alih memfilter os.path.isfile, tapi itu meninggalkan symlink yang mati dalam daftar, dan os.statakan gagal pada mereka.

Alex Coventry
sumber
4
from pathlib import Path
import os

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

atau

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

atau

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

di mana m waktu diubah waktu.

Pygirl
sumber
1

ini adalah langkah dasar untuk belajar:

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

Jawaban Alex Coventry akan menghasilkan pengecualian jika file tersebut merupakan symlink ke file yang tidak ada, kode berikut mengoreksi jawaban itu:

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

Ketika file tidak ada, sekarang () digunakan, dan symlink akan pergi di bagian paling akhir daftar.

Paolo Benvenuto
sumber
0

Berikut adalah beberapa garis sederhana yang mencari ekstensi serta menyediakan opsi pengurutan

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

Untuk kelengkapan dengan os.scandir(2x lebih cepat dari pathlib):

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

Ini versi saya:

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
sumber
Dalam kode saya, file diurutkan sebagai terlama hingga terbaru. Untuk mendapatkan nama file atau folder terbaru terlebih dahulu, Anda perlu menambahkan reverse = True dalam daftar file (dalam kasus saya itu x). jadi, x = diurutkan (os.listdir (), key = os.path.getctime, reverse = True)
haqrafiul
-6

Mungkin Anda harus menggunakan perintah shell. Di Unix / Linux, find piped with sort mungkin akan dapat melakukan apa yang Anda inginkan.

stephanea
sumber