ディレクトリから古いファイルを削除して、最新のファイルを3つだけ残そうとしています。
cd /home/user1/test
while [ `ls -lAR | grep ^- | wc -l` < 3 ] ; do
rm `ls -t1 /home/user/test | tail -1`
echo " - - - "
done
条件文に問題があります。
ファイルをループする場合は、 ls
を使用しないでください *。 tl; dr間違ったファイル、またはすべてのファイルを削除してしまう状況はたくさんあります。
とは言っても、残念ながらこれはBashで正しく行うにはトリッキーなことです。で実用的な答えがあります a 重複する質問私のさらに古いfind_date_sorted
これは小さな変更で使用できます:
counter=0
while IFS= read -r -d '' -u 9
do
let ++counter
if [[ counter -gt 3 ]]
then
path="${REPLY#* }" # Remove the modification time
echo -e "$path" # Test
# rm -v -- "$path" # Uncomment when you're sure it works
fi
done 9< <(find . -mindepth 1 -type f -printf '%TY-%Tm-%TdT%TH:%TM:%TS %p\0' | sort -rz) # Find and sort by date, newest first
*攻撃的な人はいません-私も以前にls
を使用しました。しかし、それは本当に安全ではありません。
編集: 新しいfind_date_sorted
ユニットテストあり。
はるかに簡単な方法は、zshとその glob qualifiers :Om
を使用して、年齢(つまり最も古いもの)と[1,3]
最初の3つの一致のみを保持します。
rm ./*(Om[1,3])
他の例については zshでグロブをフィルタリングする方法 も参照してください。
そして、注意してください l0b0のアドバイス :シェルの特殊文字を含むファイル名がある場合、コードはひどく壊れます。
Zsh globを使用して最新の3つのファイルを除くすべてを削除するには、Om
(大文字のO)を使用してファイルを古いものから新しいものに並べ替え、添え字を使用して必要なファイルを取得します。
rm ./*(Om[1,-4])
# | |||| ` stop at the 4th to the last file (leaving out the 3 newest)
# | |||` start with first file (oldest in this case)
# | ||` subscript to pick one or a range of files
# | |` look at modified time
# | ` sort in descending order
# ` start by looking at all files
その他の例:
# delete oldest file (both do the same thing)
rm ./*(Om[1])
rm ./*(om[-1])
# delete oldest two files
rm ./*(Om[1,2])
# delete everything but the oldest file
rm ./*(om[1,-2])
次の関数を使用して、ディレクトリ内の最新のファイルを取得できます。
newest_in()
{
local newest=$1
for f;do [[ $f -nt $newest ]] && newest="$f"; done;
printf '%s\n' "$newest"
}
各反復後に最新のファイルを除外して、異なるファイルのセットを提供します。
ヒント:「$ {files [@]}」という配列にファイルの初期セットを保持している場合は、見つかった最新のファイルのインデックスを保存し、unset 'files[index]'
次の反復の前。
使用法:newest_in [set of files/directories]
サンプル出力:
[rany$] newest_in ./*
foo.txt
[rany$]