我正在編寫一個Python備份腳本,我需要找到目錄(及其子目錄)中最舊的文件。我還需要將其過濾到* .avi文件中。在目錄中查找最舊的文件(遞歸)
該腳本將始終在Linux機器上運行。有什麼方法可以在Python中執行,或者運行一些shell命令會更好嗎?
目前我正在運行df
以獲得特定分區上的可用空間,並且如果少於5 GB可用空間,我想要開始刪除最早的*.avi
文件,直到滿足該條件。
我正在編寫一個Python備份腳本,我需要找到目錄(及其子目錄)中最舊的文件。我還需要將其過濾到* .avi文件中。在目錄中查找最舊的文件(遞歸)
該腳本將始終在Linux機器上運行。有什麼方法可以在Python中執行,或者運行一些shell命令會更好嗎?
目前我正在運行df
以獲得特定分區上的可用空間,並且如果少於5 GB可用空間,我想要開始刪除最早的*.avi
文件,直到滿足該條件。
嗯。娜迪婭的回答更接近你要求的意思是;然而,在一棵樹上發現了(單)最早的文件,試試這個:
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,因此請注意指向其他設備的任何符號鏈接,我們可以刪除多個文件,而不實際釋放此設備中的空間。
UPDATE(複製胡安評論):
取決於操作系統和文件系統實現,您可能希望通過f_frsize而不是f_bsize繁殖f_bfree。在一些實現中,後者是優選的I/O請求大小。例如,在我剛剛測試的FreeBSD 9系統上,f_frsize是4096,f_bsize是16384. POSIX表示塊計數字段「以f_frsize爲單位」(請參見http://pubs.opengroup.org/onlinepubs/9699919799//basedefs/sys_statvfs.h.html)
根據操作系統和文件系統的實現,您可能希望將'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 – Juan 2015-05-23 21:39:11
@Juan非常感謝你! – tzot 2015-05-25 06:15:37
要做到這一點在Python中,你可以使用os.walk(path)
超過文件遞歸迭代,和st_size
和st_mtime
屬性os.stat(filename)
來獲取文件大小和修改時間。
我認爲最簡單的方法是使用find和ls -t(按時間排序文件)。
東西沿着這些線路應該做的伎倆(刪除指定目錄下的最古老的AVI文件)
find/-name "*.avi" | xargs ls -t | tail -n 1 | xargs rm
步步....
查找/ -name 「* .AVI」 - 從根目錄開始遞歸查找所有avi文件
xargs ls -t - 按修改時間找到的所有文件,從最新到最舊。
尾-n 1 - 搶在列表的最後一個文件(最早)
xargs的RM - 並刪除它
他提到在循環中運行它。由於'find'往往是一個昂貴的操作,因此保留'xargs ls'的結果(可能是一個數組變量)並從中一次提取文件名可能是一個好主意。 – 2009-05-08 00:29:02
或許用find和grep替換find? – 2009-05-08 00:58:27
這是另一個Python公式, -school相比其他一些,但很容易修改,並處理沒有匹配的文件,而不引發異常的情況。
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()
等待如何使用du獲得空閒空間?這隻會告訴用法AFAIK。 – 2009-05-08 00:32:18
對不起,意思是不是du。 – 2009-05-08 00:40:13
你確定它不是df? :P – 2009-05-08 00:41:48