web-dev-qa-db-ja.com

Bashスクリプトを使用して、ディレクトリ全体のすべてのファイル(最新の4つを除く)を削除します

ディレクトリのリストに移動し、最近作成された4つのファイルを除くすべてを削除するBashスクリプトを探しています。

これどうやってするの?

7
Marv1n
ls -t | sed '1,4d' | xargs echo rm

満足のいく結果が得られたら、echoを削除します。

スペースを含むファイル名がある場合は、さらに作業が必要です。

6
glenn jackman

各ディレクトリに最新の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」を削除して効果的にする必要があります。最初に注意深くテストしてください!

0
ZILjr

これはあなたが求めているものではないことはわかっていますが、この種のバックアップでは、新しいログファイルを作成する前にログファイルをローテーションすることを好みます。次のように、もう少し明示的で、コーディングがはるかに簡単です。

#!/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
...
0
ed.

このコマンドは機能するはずです

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コマンドが生成および実行されます。

0
artistoex

最も簡単な方法:

for d in dir1 dir2 dir3; do
  rm -vf `ls -1t $d | head -n-4` 
done
0
Zarick Lau