2009-05-07 16 views
9

私はPythonのバックアップスクリプトを書いています。ディレクトリ(およびそのサブディレクトリ)で最も古いファイルを探す必要があります。また、* .aviファイルのみにフィルタリングする必要があります。ディレクトリ内でもっとも古いファイルを(再帰的に)検索する

スクリプトは常にLinuxマシン上で実行されます。 Pythonでこれを行うにはいくつかの方法がありますか、いくつかのシェルコマンドを実行する方が良いでしょうか?私は特定のパーティションの空き領域を取得するためにdfを実行しているよ、とフリー未満5ギガバイトがある場合、私はその条件が満たされるまで、最も古い*.aviファイルの削除を開始します。現時点で

+1

どのように空き領域を得るためにduを使用していますか?それはAFAIKの使い方だけを示しています。 –

+0

申し訳ありませんが、dhではありません。 –

+1

あなたはdfではないと確信していますか? :P –

答えて

21

フムを削除します。ナディアの答えはあなたに近いです。を意味します。しかし、ツリーに(シングル)最も古いファイルを見つけるために、これを試してみてください。

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) 

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最も古いファイルを取得することができます

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

つ以上の拡張子を選択する:.endswithメソッドを使用するなどの通話ができることに注意してください。

最後に、あなたは修正時間順ファイルの完全なリストを、望むならば、空きスペースに必要な数を削除するために、ここでいくつかのコードです:

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()を実行します。

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は次のとおりです。ところで

、あなたの問題を完全に解決するために、あなたはos.statvfsが利用可能なLinuxでは、上で実行されているので、あなたが行うことができますブロックサイズ。我々はrootfolder statvfsを取るので、実際にこのデバイスのスペースを解放せずに多くのファイルを削除できる他のデバイスを指し示すシンボリックリンクに気をつけてください。 (フアンによるコメントをコピー)

UPDATE:OSやファイルシステムの実装に応じて

、あなたは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参照)。

+1

OSとファイルシステムの実装に依存して、 'f_bfree'に' f_bsize'ではなく 'f_frsize'を掛けることができます。いくつかの実装では、後者が優先I/O要求サイズです。例えば、私がテストしたばかりのFreeBSD 9システムでは、 'f_frsize'は4096、' f_bsize'は16384でした。POSIXは、ブロック数フィールドは "f_frsizeの単位で"と言います - http://pubs.opengroup.org/onlinepubs/ 9699919799 //基調講演/ sys_statvfs.h.html – Juan

+0

@元は大変ありがとう! – tzot

2

linuxコマンドfindを参照してください。

また、this postは、ディレクトリ内の最も古いファイルを削除するためにlsとtailを一緒にパイプします。これは、十分な空き領域がないときにループで実行できます。参考のため

、ここではそれをしないシェルコードは(より多くの選択肢と議論のためのリンクをたどって)です:

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

Pythonでそれを行うには、ファイルの上に再帰的に反復するos.walk(path)を使用することができ、ファイルのサイズと変更時刻を取得するためにst_sizest_mtimeの属性はos.stat(filename)です。

10

あなたは最終修正時刻をファイルに

をst_mtimeのREFEREを見つけるために一緒にstatfnmatchモジュールを使用することができます。

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]) 
0

os moduleは、Pythonでディレクトリリストとファイル情報を取得するために必要な機能を提供します。私はos.walkがディレクトリを再帰的に歩くのに便利であることを発見しました。そして、os.statは各エントリに詳細な情報(変更時間を含む)を与えます。

単純なシェルコマンドを使用すると、これを簡単に行うことができます。それがあなたのためにうまくいくかどうかは、結果をどうしたいかによって決まります。

7

私はこれを行う最も簡単な方法は、ls -t(時間でソートファイル)と一緒にfindを使うことだと思います。

これらの線に沿って何かがトリックを行う必要があります(指定したディレクトリの下の最も古いAVIファイルを削除します)

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

ステップバイステップでは....

は/ -nameを見つける "* .AVI"すべてのaviファイルをルートディレクトリから再帰的に検索する

xargs ls -t - 最新のものから古いものまでのすべてのファイルをソートします。

尾-n 1 - (最古)

xargsのはをRMリストの最後のファイルをつかむ - それ

+0

彼はこれをループで実行していると言います。 'find'は高価な処理になる傾向がありますので、' xargs ls'の結果を(おそらく配列変数に)保存し、一度に1つずつファイル名を引き出す方が良いでしょう。 –

+0

おそらく、findをlocateとgrepに置き換えますか? –

2

もう少し古い - いくつかの他のものと比較して学校では、変更するのは簡単ですが、例外を発生させずに一致するファイルがない場合を処理します。

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() 
関連する問題