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

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

该脚本将始终在Linux机器上运行。 有没有办法在Python中做到这一点,或运行一些shell命令更好?

目前我正在运行df来获取特定分区上的可用空间,如果空间不足5 GB,我想要开始删除最老的*.avi文件,直到满足条件。

Solutions Collecting From Web of "在目录中查找最旧的文件(recursion)"

嗯。 纳迪亚的答案更接近你想问的问题; 但是,要查找树中(单个)最旧的文件,请尝试以下操作:

 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) 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是块大小。 我们采取rootfolder statvfs,所以介意指向其他设备的任何符号链接,在这里我们可以删除许多文件,而不会实际释放此设备中的空间。

更新(胡安复制评论):

根据操作系统和文件系统的实现,您可能希望将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 )

要在Python中执行此操作,可以使用os.walk(path)对文件进行递归迭代,并使用os.stat(filename)st_sizest_mtime属性来获取文件大小和修改时间。

您可以一起使用stat和fnmatch模块来查找文件

ST_MTIME参考上次修改时间。 如果你愿意,你可以选择另一个值

 import os, stat, fnmatch file_list = [] for filename in os.listdir('.'): if fnmatch.fnmatch(filename, '*.avi'): file_list.append((os.stat(filename)[stat.ST_MTIME], filename)) 

然后你可以按时间排序,并根据它删除。

 file_list.sort(key=lambda a: a[0]) 

我认为最简单的方法是使用find和ls -t(按时间排序)。

沿着这些线的东西应该做的伎俩(删除指定的目录下最古老的AVI文件)

 find / -name "*.avi" | xargs ls -t | tail -n 1 | xargs rm 

一步步….

find / -name“* .avi” – 从根目录开始递归查找所有avi文件

xargs ls -t – 按修改时间从最新到最旧排序找到的所有文件。

tail -n 1 – 抓取列表中的最后一个文件(最老的)

xargs RM – 并删除它

这是另外一个Python公式,与其他一些老式公式相比,但是很容易修改,并且在没有引发异常的情况下处理没有匹配文件的情况。

 import os def find_oldest_file(dirname="..", extension=".avi"): oldest_file, oldest_time = None, None for dirpath, dirs, files in os.walk(dirname): for filename in files: file_path = os.path.join(dirpath, filename) file_time = os.stat(file_path).st_mtime if file_path.endswith(extension) and (file_time<oldest_time or oldest_time is None): oldest_file, oldest_time = file_path, file_time return oldest_file, oldest_time print find_oldest_file() 

看看linux的命令find

或者, 这个帖子把 ls和tail一起管道删除一个目录中最旧的文件。 这可以在没有足够的可用空间的情况下循环完成。

作为参考,这里是壳代码(请点击链接获取更多的选择和讨论):

 ls -t -r -1 /path/to/files | head --lines 1 | xargs rm 

os模块提供了在Python中获取目录列表和文件信息所需的功能。 我发现os.walk对于递归遍历目录特别有用,os.stat会给你每个条目的详细信息(包括修改时间)。

使用简单的shell命令可能会更简单。 是否对你有好处取决于你想要对结果做什么。