ディレクトリのリストに移動し、最近作成された4つのファイルを除くすべてを削除するBashスクリプトを探しています。
これどうやってするの?
ls -t | sed '1,4d' | xargs echo rm
満足のいく結果が得られたら、echo
を削除します。
スペースを含むファイル名がある場合は、さらに作業が必要です。
各ディレクトリに最新の4つのファイルを保持しますか、それとも任意のディレクトリに最新の4つのファイルを保持しますか?
最初の問題を解決するには、findを使用して各ディレクトリを一覧表示し、それぞれのディレクトリで、最新の4つのファイルを除くすべてを削除します。これはそれほど難しいことではありません。
2番目の問題を解決するには、もう少し考えが必要ですが、実際には書くのが簡単です。
基本的に、すべてのファイルを再帰的に検索します。 「stat」コマンドを呼び出して、ファイルの変更時刻と名前を返します。これを数値で降順に並べ替え、最新の最初の4つのファイルをスキップします。
次に、先頭のタイムスタンプを削除し、結果のファイル名のリストを削除します。
(未テスト)のようなもの:
#!/bin/bash
find "$@" -type f -print0 \
| xargs -0 stat -c$'%Y\t%n' \
| sort -rn \
| awk -F$'\t' 'NR > 4 {print $2}' \
| while read f; do
echo rm -v "${f}"
done
これは機能するはずですが、whileループの「echo」を削除して効果的にする必要があります。最初に注意深くテストしてください!
これはあなたが求めているものではないことはわかっていますが、この種のバックアップでは、新しいログファイルを作成する前にログファイルをローテーションすることを好みます。次のように、もう少し明示的で、コーディングがはるかに簡単です。
#!/bin/bash
#Archive old backups
move () {
if [ -e $1 ]
then
echo "Archiving old backups: $1 to $2"
mv -f $1 $2 || echo "FAILED"
fi
}
#Bump each backup +1
rm -rf backup.4
move backup.3.tgz backup.4.tgz
move backup.2.tgz backup.3.tgz
move backup.1.tgz backup.2.tgz
move backup.tgz backup.1.tgz
#Now create today's backup
...
このコマンドは機能するはずです
find PATH1 PATH2 PATH3 -type f -printf '%T@ %p\n'|sort -nr|tail -n+5|cut -f 2- -d " "|xargs -i rm {}
コマンドでファイルを再帰的に削除したくない場合は、-maxdepth 1
の前にオプション-type f
を追加します。
このコマンドは、各ファイルを最後の変更日(find PATH1 PATH2 PATH3 -type f -printf '%T@ %p\n'
)で再帰的に出力し、リストを日付(sort -nr
)で並べ替え、最初の4つのエントリ(tail -n+5
)をスキップします。最後に、時間情報が削除され(cut -f 2- -d " "
)、結果がxargsに渡され、対応するrmコマンドが生成および実行されます。
最も簡単な方法:
for d in dir1 dir2 dir3; do
rm -vf `ls -1t $d | head -n-4`
done