【问题标题】:How to get the latest file in a folder?如何获取文件夹中的最新文件?
【发布时间】:2017-01-12 14:44:31
【问题描述】:

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

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

我收到以下错误:

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

【问题讨论】:

  • 您要查找哪个文件?将您的相关代码添加到问题中。
  • 我猜为什么它可能对您不起作用:“文件”是文件名元素列表还是单个文件名字符串?

标签: python python-3.x python-2.7


【解决方案1】:

大多数答案都是正确的,但如果需要获取最新的两个或三个最新的,那么它可能会失败或需要修改代码。

我发现下面的示例更有用和相关,因为我们也可以使用相同的代码来获取最新的 2,3 和 n 文件。

import glob
import os

folder_path = "/Users/sachin/Desktop/Files/"
files_path = os.path.join(folder_path, '*')
files = sorted(glob.iglob(files_path), key=os.path.getctime, reverse=True) 
print (files[0]) #latest file 
print (files[0],files[1]) #latest two files

【讨论】:

    【解决方案2】:

    我缺乏评论的声誉,但来自 Marlon Abeykoons 的 ctime 回应并没有为我提供正确的结果。不过,使用 mtime 可以解决问题。 (key=os.path.getmtime))

    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 does not return latest Difference between python - getmtime() and getctime() in unix system

    【讨论】:

    • 在 Mac 上 getctime 也是错误的结果,getmtime 也为我修复了它。
    【解决方案3】:

    分配给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)
    

    【讨论】:

    • 如果我想查找最新创建/修改的文件夹而不是文件怎么办?
    • @Link 相同的代码适用于此。如果你想检查它的文件夹,你可以检查if os.path.isdir(latest_file):
    • 很奇怪。我不得不使用“min”来获取最新的文件。一些搜索暗示它是特定于操作系统的。
    • 这是一个很好的答案——谢谢!我更喜欢使用 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 你仍然可以使用os.path.getctime 作为键,即使是Path 对象。
    【解决方案4】:

    我一直在 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)
    

    【讨论】:

      【解决方案5】:

      我建议使用glob.iglob() 而不是glob.glob(),因为它更有效。

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

      这意味着glob.iglob() 会更有效率。

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

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


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

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

      【讨论】:

      • 我喜欢这个max() 排序。就我而言,我使用了不同的key=os.path.basename,因为文件名中包含时间戳。
      【解决方案6】:

      在 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 是无。

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

      【讨论】:

      • 不知道为什么这会吸引反对票,对于那些需要快速完成这项任务的人来说,这是我能找到的最快的方法。有时需要非常快速地完成此操作。
      • 点个赞。我不在 Windows 中这样做,但如果您正在寻找速度,其他答案需要迭代目录中的所有文件。因此,如果您的操作系统中指定列出文件排序顺序的 shell 命令可用,则提取该文件的第一个或最后一个结果应该更快。
      • 谢谢,我实际上更关心比这更好的解决方案(就像在同样快速但纯 python 中)所以希望有人能详细说明。
      • 抱歉,我不得不投反对票,我会礼貌地解释原因。最大的原因是它没有使用 python(不是跨平台的)因此被破坏,除非在 Windows 下运行。其次,这不是一种“更快的方法”(除非更快意味着快速且不麻烦地阅读文档)--shelling out to another script 非常慢。
      • @MarkHu 实际上这个脚本的诞生是为了从 python 脚本中快速检查一个大文件夹的内容。因此,在这种情况下,更快的方法意味着,以最快的速度(或比纯 python 方法更快)获取最新文件夹的文件名。随意为 linux 添加一个类似的脚本,可能基于ls -Art | tail -n 1。请在声明解决方案之前评估其性能。
      【解决方案7】:

      我尝试使用上述建议并且我的程序崩溃了,然后我发现我尝试识别的文件已被使用,并且在尝试使用“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,'*'))))
      

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

      【讨论】:

        【解决方案8】:
        max(files, key = os.path.getctime)
        

        是相当不完整的代码。 files 是什么?它可能是来自os.listdir() 的文件名列表。

        但是这个列表只列出了文件名部分(又名“basenames”),因为它们的路径是通用的。为了正确使用它,您必须将它与通向它的路径结合起来(并用于获取它)。

        如(未经测试):

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

        【讨论】:

        • 我相信反对者可以解释到底是什么问题。
        • 不知道,为你测试过,它似乎确实有效。最重要的是,你是唯一一个愿意解释一下的人。阅读接受的答案让我认为需要'glob'的东西,而它绝对不是。谢谢
        • @David 当然。只需将if basename.endswith('.csv') 插入列表理解即可。
        • @BreakBadSP 如果您想要灵活性,那您是对的。如果您仅限于某个目录,我看不出您的目录如何更有效率。但有时,可读性比效率更重要,所以从这个意义上说,你的可能确实更好。
        • 感谢您,我在很多 ETL 函数中都使用了它!
        【解决方案9】:

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

        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]
        

        【讨论】:

          【解决方案10】:

          (已编辑以改进答案)

          首先定义一个函数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 部分?
          • 这在 Windows 10 下的 0 长度文件上失败。
          猜你喜欢
          • 2023-02-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-07-08
          • 1970-01-01
          • 1970-01-01
          • 2015-03-22
          相关资源
          最近更新 更多