当前位置: 首页 > 面试题库 >

在目录中查找最旧的文件(递归)

柳高卓
2023-03-14
问题内容

我正在编写一个Python备份脚本,需要在目录(及其子目录)中找到最旧的文件。我还需要仅将其过滤为* .avi文件。

该脚本将始终在Linux计算机上运行。有什么方法可以在Python中完成,还是运行一些Shell命令会更好?

目前,我正在df努力获取特定分区上的可用空间,如果可用空间不足5 GB,我想开始删除最旧的*.avi文件,直到满足该条件为止。


问题答案:

嗯 Nadia的答案是接近你什么 意思 要问; 但是,要在树中找到(单个)最旧的文件,请尝试以下操作:

import os
def oldest_file_in_tree(rootfolder, extension=".avi"):
    return min(
        (os.path.join(dirname, filename)
        for dirname, dirnames, filenames in os.walk(rootfolder)
        for filename in filenames
        if filename.endswith(extension)),
        key=lambda fn: os.stat(fn).st_mtime)

稍作修改,就可以得到n最旧的文件(类似于Nadia的答案):

import os, heapq
def oldest_files_in_tree(rootfolder, count=1, extension=".avi"):
    return heapq.nsmallest(count,
        (os.path.join(dirname, filename)
        for dirname, dirnames, filenames in os.walk(rootfolder)
        for filename in filenames
        if filename.endswith(extension)),
        key=lambda fn: os.stat(fn).st_mtime)

请注意,使用该.endswith方法允许调用为:

oldest_files_in_tree("/home/user", 20, (".avi", ".mov"))

选择多个扩展名。

最后,如果您想要按修改时间排序的完整文件列表,以便根据需要删除尽可能多的文件以释放空间,请使用以下代码:

import os
def files_to_delete(rootfolder, extension=".avi"):
    return sorted(
        (os.path.join(dirname, filename)
         for dirname, dirnames, filenames in os.walk(rootfolder)
         for filename in filenames
         if filename.endswith(extension)),
        key=lambda fn: os.stat(fn).st_mtime),
        reverse=True)

并注意,reverse=True最早的文件位于列表的末尾,因此对于下一个要删除的文件,只需执行即可file_list.pop()

顺便说一句,为了完全解决您的问题,由于您正在Linux上运行(如果有os.statvfs),您可以执行以下操作:

import os
def free_space_up_to(free_bytes_required, rootfolder, extension=".avi"):
    file_list= files_to_delete(rootfolder, extension)
    html" target="_blank">while file_list:
        statv= os.statvfs(rootfolder)
        if statv.f_bfree*statv.f_bsize >= free_bytes_required:
            break
        os.remove(file_list.pop())

statvfs.f_bfree是设备可用块,statvfs.f_bsize是块大小。我们使用rootfolderstatvfs,因此请注意指向其他设备的任何符号链接,我们可以在其中删除许多文件而无需实际释放此设备中的空间。

更新(复制Juan的评论):

根据操作系统和文件系统的实现,您可能希望将f_bfree乘以f_frsize而不是f_bsize。在某些实现中,后者是首选的I /
O请求大小。例如,在我刚刚测试的FreeBSD
9系统上,f_frsize为4096,f_bsize为16384。POSIX说,块计数字段是“以f_frsize为单位”(请参见http://pubs.opengroup.org/onlinepubs/9699919799//
basedefs /
sys_statvfs.h.html




 类似资料:
  • 问题内容: 我正在尝试将一个自动化脚本输入到最近创建的文件夹中。 我下面有一些代码 我不确定如何从现在开始检查最新的时间戳。有任何想法吗? 谢谢 问题答案: 还有的“创建时间”在大多数OS /文件系统没有实际的跟踪:你得到的是一个文件或目录的时间 修改 (因此,例如创建一个目录中的文件更新该目录的修改时间) -和,如果提供,则表示最新的inode更改时间(因此将通过创建或删除子目录来更新)。 假设

  • 问题内容: 我正在尝试获取目录中所有文本文件的名称。如果目录中包含子目录,那么我也想在这些子目录中获取任何文本文件。我不确定如何继续执行任意数量的子目录。 现在,下面的代码仅获取当前目录中的所有文本文件以及该目录中的子目录。对于找到的每个子目录,它还会找到任何文本文件和更深的子目录。问题是,如果那些更深的子目录还有更深的子目录,那么我找不到所有的文本文件。这似乎是一个需要递归的问题,因为我不知道它

  • 我需要使用php读取目录中的所有文件。所以我需要这样的回报 我的文件如下所示: 现在一切正常,但是在运行之前我必须自己输入这些文件。如何从目录中发布所有文件?现在我有这样的: 我尝试了用lolob()、scandir()和readdir(),但是我没有得到想要的结果。谢谢!

  • 我有一个文件夹,其中包含子文件夹和一些其他文件。 这些文件的命名方式如下 我试图在上面的模式中找到只与“xxxxxx”匹配的重复文件,忽略其余的。分机。dat没有改变。但是abc和DEF的长度可能会改变。按周期划分的顺序也不会改变。 我猜我需要用下面的方式使用Find 我需要帮助想出正则表达式。谢谢 例如:对于名为“epg”的文件。ktt。crwqdd。dat,我需要找到包含“crwqdd”的重复

  • 问题内容: 我试图找到一种方法来检测何时将闪存驱动器插入计算机。到目前为止,我发现的解决方案是轮询更改。这确实告诉我何时插入了闪存驱动器,但是据我所知,没有办法为其找到位置。而双方似乎非常不可靠作为其返回值是实现特定的,但他们似乎是可能返回的任何相关信息,可能有助于找到该目录的唯一方法。 考虑到这一点,以下代码: 给我这个输出: 事实证明,返回驱动器的格式并返回该驱动器的设备文件的位置。据我所知,

  • 问题内容: 我有一个包含约1000个文件名的列表,可在目录及其子目录下进行搜索。有数百个具有超过1,000,000个文件的子目录。以下命令将运行find 1000次: 有更快的方法吗? 问题答案: 如果每行只有一个文件名: (该选项意味着grep搜索给定文件中的所有模式。) 的说明: 在被称为过程subsitution,并且有点类似。这种情况是等效的(但是使用流程替换更整洁,可能更快一些): 调用