如何使用python获取文件夹中的最新文件


126

我需要使用python获取文件夹的最新文件。使用代码时:

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

我收到以下错误:

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


2
您尝试查找哪个文件?将您的相关代码添加到问题中。
Naeem Ul Wahhab

1
我正在猜测为什么它可能对您不起作用:“文件”是文件名元素列表还是单个文件名字符串?
mpurg

Answers:


322

分配给files变量的任何内容均不正确。使用以下代码。

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
如果要查找最新创建/修改的文件夹而不是文件怎么办?
链接

1
@Link相同的代码适用于此。如果您要检查其文件夹,则可以检查if os.path.isdir(latest_file):
Marlon Abeykoon

6
奇怪的。我必须使用“ min”来获取最新文件。一些搜索表明它是特定于操作系统的。
Graeck

15
这是一个很好的答案-谢谢!我喜欢使用pathlib.Path对象而不是字符串和os.path。使用pathlib.Path对象,您的答案将变为: list_of_paths = folder_path.glob('*'); latest_path = max(list_of_paths, key=lambda p: p.stat().st_ctime)
Phil

4
@phil os.path.getctime即使对于Path对象,您仍然可以将其用作键。
Berislav Lopac '18

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

是非常不完整的代码。什么files啊 可能是来自的文件名列表os.listdir()

但是此列表仅列出了文件名部分(也称为“基本名称”),因为它们的路径是通用的。为了正确使用它,您必须将其与通向它的路径结合起来(并用于获得它)。

如(未测试):

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

3
Dunno,为您测试过,它确实有效。最重要的是,您是唯一一个需要说明的人。阅读被接受的答案使我认为需要“全局”的东西,而绝对不是。谢谢
Arnaud P

4
@David当然。只需将其插入if basename.endswith('.csv')列表中即可。
glglgl

1
@BreakBadSP如果您想要灵活性,那是对的。如果您被限制在某个目录中,我看不出您的目录如何可能更有效率。但是有时候,可读性比效率更重要,因此从这个意义上来说,您的确可能会更好。
glglgl

1
为此,我在很多ETL函数中都使用了它!
Manakin

9

我建议使用glob.iglob()代替glob.glob(),因为它效率更高。

glob.iglob()返回一个迭代器,该迭代器产生的值与glob()相同,而实际上并没有同时存储所有值。

意思是 glob.iglob()效率更高。

我主要使用以下代码查找与我的模式匹配的最新文件:

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


注意:max函数有多种变体,如果找到最新文件,我们将使用以下变体: max(iterable, *[, key, default])

它需要迭代,因此您的第一个参数应该是可迭代的。如果找到最大数量,我们可以使用beow变体:max (num1, num2, num3, *args[, key])


1
我喜欢这种max()。在我的情况下,我使用了不同的名称,key=os.path.basename因为文件名中带有时间戳。
MarkHu '19

4

尝试按创建时间对项目排序。以下示例对文件夹中的文件进行排序,并获取最新的第一个元素。

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

我缺乏发表评论的声誉,但是Marlon Abeykoons回应的ctime并未为我提供正确的结果。使用mtime可以解决问题。(key = os.path.get m时间))

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

对于该问题,我找到了两个答案:

python os.path.getctime max不返回最新的 python-unix系统中的getmtime()和getctime()之间的区别


1

(编辑以改善答案)

首先定义一个函数get_latest_file

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

您也可以使用文档字符串!

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)

如果使用Python 3,则可以改用iglob

完成代码以返回最新文件的名称:

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

JuniperAccessLog-standalone-FCL_VPN从哪里得到零件?
glglgl

这在Windows 10下长度为0的文件上失败
。– Superdooperhero

1

我试图使用以上建议,但程序崩溃了,而不是我想识别的文件已被使用,并且在尝试使用“ os.path.getctime”时崩溃了。最终对我有用的是:

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

此代码获取了两组文件列表之间最常见的对象,它并不是最优雅的对象,如果同时创建多个文件,则可能会不稳定


1

在Windows(0.05s)上更快的方法是,调用执行此操作的bat脚本:

get_latest.bat

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

\\directory\in\question您要调查的目录在哪里。

get_latest.py

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

如果找到文件stdout是路径,stderr则为None。

使用stdout.decode("utf-8").rstrip()来获取文件名使用字符串表示。


不知道为什么会这么吸引人,对于那些需要快速执行此任务的人来说,这是我能找到的最快的方法。有时有必要非常快地执行此操作。
ic_fl2

进行投票。我不是在Windows中执行此操作,但是如果您正在寻找速度,则其他答案需要对目录中的所有文件进行迭代。因此,如果您的OS中指定了列出文件排序顺序的Shell命令可用,则拉出第一个或最后一个结果应该更快。
Jim Hunziker

1
谢谢,我实际上更关心的是一个比此更好的解决方案(例如,同样快速但纯Python),因此希望有人能对此进行详细说明。
ic_fl2

2
抱歉,但是我不得不投票,我将礼貌地解释原因。最大的原因是,除非在Windows下运行,否则它不会使用python(非跨平台)中断。其次,这不是一个“更快的方法”(除非更快意味着没有快速而肮脏的阅读文档)-炮轰另一个脚本的速度非常慢。
MarkHu '19

1
@MarkHu实际上,此脚本是出于从python脚本快速检查大文件夹内容的需要而诞生的。因此,在这种情况下,更快的方法意味着以最快的速度(或比纯python方法更快)获取最新文件夹的文件名。随意为linux添加一个类似的脚本,可能基于ls -Art | tail -n 1。在提出解决方案之前,请先评估解决方案的性能。
ic_fl2

0

我在Python 3中一直在使用它,包括在文件名上进行模式匹配。

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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.