Cara mendapatkan file terbaru di folder menggunakan python

126

Saya perlu mendapatkan file terbaru dari sebuah folder menggunakan python. Saat menggunakan kode:

max(files, key = os.path.getctime)

Saya mendapatkan kesalahan di bawah ini:

FileNotFoundError: [WinError 2] The system cannot find the file specified: 'a'

garlapak
sumber
2
File mana yang Anda coba temukan? tambahkan kode Anda yang relevan ke quesiton.
Naeem Ul Wahhab
1
Saya menebak mengapa ini mungkin tidak berhasil untuk Anda: apakah "file" adalah daftar elemen nama file atau string nama file tunggal?
mpurg

Jawaban:

323

Apapun yang ditugaskan ke filesvariabel salah. Gunakan kode berikut.

import glob
import os

list_of_files = glob.glob('/path/to/folder/*') # * means all if need specific format then *.csv
latest_file = max(list_of_files, key=os.path.getctime)
print latest_file
Marlon Abeykoon
sumber
4
Bagaimana jika alih-alih file saya ingin mencari folder terbaru yang dibuat / dimodifikasi?
Tautkan
1
@Tautkan kode yang sama berfungsi untuk itu. Jika Anda ingin memeriksa foldernya atau tidak, Anda dapat memeriksaif os.path.isdir(latest_file):
Marlon Abeykoon
6
Aneh. Saya harus menggunakan "min" untuk mendapatkan file terbaru. Beberapa pencarian di sekitar mengisyaratkan bahwa itu sangat spesifik.
Graeck
15
Ini adalah jawaban yang bagus - TERIMA KASIH! Saya suka bekerja dengan pathlib.Pathobjek lebih dari sekedar string dan os.path. Dengan objek pathlib.Path jawaban Anda menjadi: list_of_paths = folder_path.glob('*'); latest_path = max(list_of_paths, key=lambda p: p.stat().st_ctime)
Phil
4
@phil Anda masih dapat menggunakan os.path.getctimesebagai kunci, bahkan dengan Pathobjek.
Berislav Lopac
42
max(files, key = os.path.getctime)

adalah kode yang tidak lengkap. Apa files? Ini mungkin adalah daftar nama file, keluar dari os.listdir().

Tetapi daftar ini hanya mencantumkan bagian nama file (alias "nama dasar"), karena jalurnya sama. Untuk menggunakannya dengan benar, Anda harus menggabungkannya dengan jalur yang mengarah ke sana (dan digunakan untuk mendapatkannya).

Seperti (belum teruji):

def newest(path):
    files = os.listdir(path)
    paths = [os.path.join(path, basename) for basename in files]
    return max(paths, key=os.path.getctime)
glglgl
sumber
Saya yakin downvoters bisa menjelaskan apa sebenarnya yang salah.
glglgl
3
Entahlah, diuji untuk Anda, tampaknya berhasil. Selain itu, Anda adalah satu-satunya yang peduli untuk menjelaskan sedikit. Membaca jawaban yang diterima membuat saya berpikir bahwa 'glob' diperlukan, padahal sama sekali tidak. Terima kasih
Arnaud P
4
@Dvid Tentu saja. Masukkan saja if basename.endswith('.csv')ke dalam pemahaman daftar.
glglgl
1
@BreakBadSP Jika Anda menginginkan fleksibilitas, Anda benar. Jika Anda dibatasi pada direktori tertentu, saya tidak melihat bagaimana Anda bisa lebih efisien. Namun terkadang, keterbacaan lebih penting daripada efisiensi, jadi keterbacaan Anda mungkin lebih baik dalam hal itu.
glglgl
1
Terima kasih untuk ini, saya telah menggunakan ini di banyak fungsi ETL saya!
Manakin
9

Saya akan menyarankan untuk menggunakan glob.iglob()daripada glob.glob(), karena lebih efisien.

glob.iglob () Kembalikan iterator yang menghasilkan nilai yang sama seperti glob () tanpa benar-benar menyimpan semuanya secara bersamaan.

Artinya glob.iglob()akan lebih hemat.

Saya kebanyakan menggunakan kode di bawah ini untuk menemukan file terbaru yang cocok dengan pola saya:

LatestFile = max(glob.iglob(fileNamePattern),key=os.path.getctime)


CATATAN: Ada varian maxfungsi, Jika menemukan file terbaru, kami akan menggunakan varian di bawah ini: max(iterable, *[, key, default])

yang membutuhkan iterable sehingga parameter pertama Anda harus dapat di iterable. Jika menemukan jumlah maksimum, kita dapat menggunakan varian beow:max (num1, num2, num3, *args[, key])

BreakBadSP
sumber
1
Saya suka yang seperti ini max(). Dalam kasus saya, saya menggunakan yang berbeda key=os.path.basenamekarena nama file memiliki cap waktu di dalamnya.
MarkHu
4

Cobalah untuk mengurutkan item berdasarkan waktu pembuatan. Contoh di bawah ini mengurutkan file dalam folder dan mendapatkan elemen pertama yang terbaru.

import glob
import os

files_path = os.path.join(folder, '*')
files = sorted(
    glob.iglob(files_path), key=os.path.getctime, reverse=True) 
print files[0]
turkus
sumber
4

Reputasi saya kurang bagus untuk berkomentar tetapi respon dari Marlon Abeykoons tidak memberikan hasil yang benar untuk saya. Menggunakan mtime memang berhasil. (key = os.path.get m waktu))

import glob
import os

list_of_files = glob.glob('/path/to/folder/*') # * means all if need specific format then *.csv
latest_file = max(list_of_files, key=os.path.getmtime)
print latest_file

Saya menemukan dua jawaban untuk masalah itu:

python os.path.getctime max tidak mengembalikan Perbedaan terbaru antara python - getmtime () dan getctime () di sistem unix

crlf
sumber
1

(Diedit untuk meningkatkan jawaban)

Pertama, tentukan fungsi get_latest_file

def get_latest_file(path, *paths):
    fullpath = os.path.join(path, paths)
    ...
get_latest_file('example', 'files','randomtext011.*.txt')

Anda juga dapat menggunakan docstring!

def get_latest_file(path, *paths):
    """Returns the name of the latest (most recent) file 
    of the joined path(s)"""
    fullpath = os.path.join(path, *paths)

Jika Anda menggunakan Python 3 , Anda dapat menggunakan iglob sebagai gantinya.

Kode lengkap untuk mengembalikan nama file terbaru:

def get_latest_file(path, *paths):
    """Returns the name of the latest (most recent) file 
    of the joined path(s)"""
    fullpath = os.path.join(path, *paths)
    files = glob.glob(fullpath)  # You may use iglob in Python3
    if not files:                # I prefer using the negation
        return None                      # because it behaves like a shortcut
    latest_file = max(files, key=os.path.getctime)
    _, filename = os.path.split(latest_file)
    return filename
Naeem Ul Wahhab
sumber
Dari mana Anda mendapatkan JuniperAccessLog-standalone-FCL_VPNbagian itu?
glglgl
Ini gagal pada 0 file panjang di bawah Windows 10.
Superdooperhero
1

Saya telah mencoba menggunakan saran di atas dan program saya macet, daripada saya menemukan file yang saya coba identifikasi digunakan dan ketika mencoba menggunakan 'os.path.getctime' itu macet. yang akhirnya berhasil bagi saya adalah:

    files_before = glob.glob(os.path.join(my_path,'*'))
    **code where new file is created**
    new_file = set(files_before).symmetric_difference(set(glob.glob(os.path.join(my_path,'*'))))

kode ini mendapatkan objek yang tidak biasa di antara dua set daftar file itu bukan yang paling elegan, dan jika banyak file dibuat pada saat yang sama itu mungkin tidak akan stabil

AlexFink
sumber
1

Metode yang jauh lebih cepat pada windows (0,05s), panggil skrip bat yang melakukan ini:

get_latest.bat

@echo off
for /f %%i in ('dir \\directory\in\question /b/a-d/od/t:c') do set LAST=%%i
%LAST%

di mana \\directory\in\questiondirektori yang ingin Anda selidiki.

get_latest.py

from subprocess import Popen, PIPE
p = Popen("get_latest.bat", shell=True, stdout=PIPE,)
stdout, stderr = p.communicate()
print(stdout, stderr)

jika menemukan file stdoutadalah path dan stderrtidak ada.

Gunakan stdout.decode("utf-8").rstrip()untuk mendapatkan representasi string yang dapat digunakan dari nama file.

ic_fl2
sumber
Tidak yakin mengapa ini menarik suara, bagi mereka yang perlu melakukan tugas ini dengan cepat ini adalah metode tercepat yang dapat saya temukan. Dan terkadang perlu melakukan ini dengan sangat cepat.
ic_fl2
Dapatkan suara positif. Saya tidak melakukan ini di Windows, tetapi jika Anda mencari kecepatan, jawaban lain memerlukan iterasi semua file dalam direktori. Jadi jika perintah shell di OS Anda yang menentukan urutan file yang terdaftar tersedia, menarik hasil pertama atau terakhir seharusnya lebih cepat.
Jim Hunziker
1
Terima kasih, saya sebenarnya lebih peduli dengan solusi yang lebih baik daripada ini (seperti pada python yang cepat tetapi murni) jadi saya berharap seseorang dapat menguraikannya.
ic_fl2
2
Maaf, tapi saya harus memberi suara negatif, dan saya akan memberi Anda penjelasan tentang alasannya. Alasan terbesar adalah tidak menggunakan python (bukan cross-platform) sehingga rusak kecuali dijalankan di bawah Windows. Kedua, ini bukan "metode yang lebih cepat" (kecuali jika lebih cepat berarti cepat-dan-kotor-tidak-mengganggu-untuk-membaca-dokumen) --menyampaikan ke skrip lain sangat lambat.
MarkHu
1
@MarkHu Sebenarnya skrip ini lahir dari kebutuhan untuk memeriksa isi folder yang besar dengan cepat dari skrip python. Jadi dalam hal ini metode yang lebih cepat berarti, mendapatkan nama file dari folder terbaru yang tercepat (atau lebih cepat dari metode python murni). Jangan ragu untuk menambahkan skrip serupa untuk linux, mungkin berdasarkan ls -Art | tail -n 1. Harap evaluasi kinerja solusi sebelum membuat klaim tentangnya.
ic_fl2
0

Saya telah menggunakan ini dengan Python 3, termasuk pencocokan pola pada nama file.

from pathlib import Path

def latest_file(path: Path, pattern: str = "*"):
    files = path.glob(pattern)
    return max(files, key=lambda x: x.stat().st_ctime)
Jamie Bull
sumber