Cách lấy tệp mới nhất trong thư mục bằng python


126

Tôi cần lấy tệp mới nhất của một thư mục bằng python. Trong khi sử dụng mã:

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

Tôi gặp lỗi dưới đây:

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


2
Bạn đang cố gắng tìm tệp nào? thêm mã có liên quan của bạn vào quesiton.
Naeem Ul Wahhab

1
Tôi đoán tại sao nó có thể không hoạt động với bạn: "tệp" là danh sách các phần tử tên tệp hay một chuỗi tên tệp duy nhất?
mpurg

Câu trả lời:


323

Bất cứ điều gì được gán cho filesbiến là không chính xác. Sử dụng mã sau.

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

4
Điều gì xảy ra nếu thay vì một tệp, tôi muốn tìm thư mục được tạo / sửa đổi mới nhất?
Liên kết

1
@Link mã tương tự hoạt động cho điều đó. Nếu bạn muốn kiểm tra một thư mục của nó hay không u có thể kiểm traif os.path.isdir(latest_file):
Marlon Abeykoon

6
Kỳ dị. Tôi đã phải sử dụng "min" để có được tệp mới nhất. Một số tìm kiếm xung quanh gợi ý rằng đó là hệ điều hành cụ thể.
Graeck

15
Đây là một câu trả lời xuất sắc - XIN CẢM ƠN! Tôi thích làm việc với pathlib.Pathcác đối tượng hơn là chuỗi và os.path. Với các đối tượng pathlib.Path, câu trả lời của bạn sẽ trở thành: list_of_paths = folder_path.glob('*'); latest_path = max(list_of_paths, key=lambda p: p.stat().st_ctime)
Phil

4
@phil Bạn vẫn có thể sử dụng os.path.getctimelàm khóa, ngay cả với Pathcác đối tượng.
Berislav Lopac

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

là mã khá không đầy đủ. Là filesgì? Nó có thể là một danh sách các tên tệp, sắp ra os.listdir().

Nhưng danh sách này chỉ liệt kê các phần tên tệp (còn gọi là "tên cơ sở"), vì đường dẫn của chúng là chung. Để sử dụng nó một cách chính xác, bạn phải kết hợp nó với đường dẫn đến nó (và được sử dụng để lấy nó).

Chẳng hạn như (chưa được kiểm tra):

def newest(path):
    files = os.listdir(path)
    paths = [os.path.join(path, basename) for basename in files]
    return max(paths, key=os.path.getctime)

Tôi chắc chắn những người phản đối có thể giải thích chính xác điều gì là sai.
glglgl

3
Dunno, đã thử nghiệm cho bạn, nó dường như hoạt động. Trên hết, bạn là người duy nhất cần giải thích một chút. Đọc câu trả lời được chấp nhận khiến tôi nghĩ rằng cần phải có thứ 'cầu', trong khi nó hoàn toàn không. Cảm ơn
Arnaud P

4
@David Tất nhiên. Chỉ cần chèn if basename.endswith('.csv')vào danh sách dễ hiểu.
glglgl,

1
@BreakBadSP Nếu bạn muốn linh hoạt, bạn đã đúng. Nếu bạn bị giới hạn trong một thư mục nhất định, tôi không thấy cách nào của bạn có thể hiệu quả hơn. Nhưng đôi khi, khả năng đọc quan trọng hơn hiệu quả, vì vậy theo nghĩa đó, tính năng của bạn thực sự có thể tốt hơn.
glglgl

1
Cảm ơn vì điều này, tôi đã sử dụng nó trong rất nhiều hàm ETL của mình!
Manakin

9

Tôi sẽ đề nghị sử dụng glob.iglob()thay vì sử dụng glob.glob(), vì nó hiệu quả hơn.

global.iglob () Trả về một trình vòng lặp mang lại các giá trị giống như global () mà không thực sự lưu trữ tất cả chúng đồng thời.

Phương tiện nào glob.iglob()sẽ hiệu quả hơn.

Tôi chủ yếu sử dụng mã dưới đây để tìm tệp mới nhất phù hợp với mẫu của tôi:

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


LƯU Ý: Có các biến thể của maxhàm, Trong trường hợp tìm thấy tệp mới nhất, chúng tôi sẽ sử dụng biến thể dưới đây: max(iterable, *[, key, default])

cần có thể lặp để tham số đầu tiên của bạn phải có thể lặp lại. Trong trường hợp tìm tối đa nums, chúng ta có thể sử dụng biến thể beow:max (num1, num2, num3, *args[, key])


1
Tôi thích kiểu này max(). Trong trường hợp của tôi, tôi đã sử dụng một tên khác key=os.path.basenamevì tên tệp có dấu thời gian trong đó.
MarkHu

4

Cố gắng sắp xếp các mục theo thời gian tạo. Ví dụ dưới đây sắp xếp các tệp trong một thư mục và nhận phần tử đầu tiên là phần tử mới nhất.

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]

4

Tôi không có danh tiếng để bình luận nhưng ctime từ phản hồi của Marlon Abeykoons không đưa ra kết quả chính xác cho tôi. Sử dụng mtime thực hiện thủ thuật. (key = os.path.get m time))

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

Tôi đã tìm thấy hai câu trả lời cho vấn đề đó:

python os.path.getctime max không trả về mới nhất Sự khác biệt giữa python - getmtime () và getctime () trong hệ thống unix


1

(Đã chỉnh sửa để cải thiện câu trả lời)

Đầu tiên hãy xác định một hàm get_latest_file

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

Bạn cũng có thể sử dụng một chuỗi tài liệu!

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)

Nếu bạn sử dụng Python 3 , bạn có thể sử dụng iglob để thay thế.

Hoàn thành mã để trả về tên của tệp mới nhất:

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

Bạn lấy JuniperAccessLog-standalone-FCL_VPNmột phần từ đâu?
glglgl

Đây không thành công trên 0 chiều dài tập tin trong môi trường Windows 10
Superdooperhero

1

Tôi đã cố gắng sử dụng các đề xuất trên và chương trình của tôi bị lỗi, tôi đã tìm ra tệp mà tôi đang cố xác định đã được sử dụng và khi cố gắng sử dụng 'os.path.getctime', nó đã bị lỗi. những gì cuối cùng đã làm việc cho tôi là:

    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,'*'))))

mã này nhận được đối tượng không phổ biến giữa hai tập hợp danh sách tệp không phải là đối tượng tốt nhất và nếu nhiều tệp được tạo cùng một lúc, nó có thể sẽ không ổn định


1

Một phương pháp nhanh hơn nhiều trên windows (0,05 giây), gọi một tập lệnh bat thực hiện điều này:

get_latest.bat

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

đâu \\directory\in\questionlà thư mục bạn muốn điều tra.

get_latest.py

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

nếu nó tìm thấy một tệp stdoutlà đường dẫn và stderrlà Không.

Sử dụng stdout.decode("utf-8").rstrip()để lấy biểu diễn chuỗi có thể sử dụng của tên tệp.


Không chắc tại sao điều này lại thu hút phiếu bầu, đối với những người cần thực hiện nhiệm vụ này nhanh chóng thì đây là phương pháp nhanh nhất mà tôi có thể tìm thấy. Và đôi khi nó là cần thiết để làm điều này rất nhanh chóng.
ic_fl2

Có một ủng hộ. Tôi không làm điều này trong Windows, nhưng nếu bạn đang tìm kiếm tốc độ, các câu trả lời khác yêu cầu lặp lại tất cả các tệp trong một thư mục. Vì vậy, nếu các lệnh shell trong hệ điều hành của bạn chỉ định thứ tự sắp xếp của các tệp được liệt kê có sẵn, thì việc kéo kết quả đầu tiên hoặc cuối cùng của điều đó sẽ nhanh hơn.
Jim Hunziker

1
Cảm ơn tôi thực sự quan tâm đến một giải pháp tốt hơn điều này (như trong python nhanh nhưng tinh khiết tương tự) vì vậy tôi hy vọng ai đó có thể giải thích rõ hơn về điều đó.
ic_fl2

2
Xin lỗi, nhưng tôi phải từ chối và tôi sẽ nhã ý giải thích lý do tại sao. Lý do lớn nhất là nó không sử dụng python (không phải đa nền tảng) do đó bị hỏng trừ khi chạy trong Windows. Thứ hai, đây không phải là một "phương pháp nhanh hơn" (trừ khi nhanh hơn có nghĩa là tài liệu nhanh chóng và bẩn thỉu-không-làm-phiền-phức-tạp) - việc thanh toán cho một tập lệnh khác nổi tiếng là chậm.
MarkHu

1
@MarkHu Trên thực tế, tập lệnh này được sinh ra vì sự cần thiết để kiểm tra nhanh chóng nội dung của một thư mục lớn từ một tập lệnh python. Vì vậy, trong trường hợp này, phương pháp nhanh hơn có nghĩa là, lấy tên tệp của thư mục mới nhất nhanh nhất (hoặc nhanh hơn phương pháp python thuần túy). Vui lòng thêm một tập lệnh tương tự cho linux, có thể dựa trên ls -Art | tail -n 1. Vui lòng đánh giá hiệu suất của giải pháp trước khi đưa ra tuyên bố về giải pháp đó.
ic_fl2

0

Tôi đã sử dụng điều này trong Python 3, bao gồm cả đối sánh mẫu trên tên tệp.

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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.