Yanıtlar:
Dosyalar arasında döngü yapmak istiyorsanız, aslals
* kullanmayın . tl; dr Yanlış dosyayı hatta tüm dosyaları silebileceğiniz birçok durum vardır.
Bununla birlikte, maalesef bu Bash'te yapmak zor bir şey. Küçük değişikliklerle kullanabileceğiniz daha da yaşlı bir soruya cevap veren bir soru var :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
* Suçsuz çocuklar - Daha ls
önce de kullandım . Ama gerçekten güvenli değil.
Düzenleme: Yenifind_date_sorted
ünite testleri ile.
((++counter>3))
test olarak dene . Güzel, kısa ve öz. Onelinerlere gelince: Eğer kısalık bir endişe ise kodu bir fonksiyona sarın, o zaman endişelenmeyin.
Bir zsh glob kullanarak en yeni 3 dosya dışındaki tüm dosyaları silmek için Om
(büyük O) ile dosyaları en eskiden en yeniye doğru sıralamak için ve bir alt betiği kullanarak istediğiniz dosyaları alabilirsiniz.
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
Diğer örnekler:
# 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])
Şimdiye kadar en kolay yöntem zsh ve glob elemelerini kullanmaktır : Om
yaşı azaltarak (yani ilk önce en eski) sıralamak ve [1,3]
sadece ilk üç maçı tutmaktır.
rm ./*(Om[1,3])
Ayrıca bakınız ben zsh içinde bir topak nasıl filtre Daha fazla örnek için.
Ve l0b0'ın tavsiyelerine dikkat edin : kabuk özel karakterleri içeren dosya adlarınız varsa kodunuz korkunç bir şekilde kırılacaktır.
Bir dizindeki en yeni dosyayı almak için aşağıdaki işlevi kullanabilirsiniz:
newest_in()
{
local newest=$1
for f;do [[ $f -nt $newest ]] && newest="$f"; done;
printf '%s\n' "$newest"
}
Her yinelemeden sonra en yeni dosyayı dışlayarak farklı bir dosya kümesi verin.
İpucu: İlk dosya kümesini "$ {files [@]}" adlı bir dizide tutarsanız, bulunan en yeni dosyanın dizinini ve bir unset 'files[index]'
sonraki yinelemeden önce kaydedin .
Kullanımı: newest_in [set of files/directories]
Örnek çıktı:
[rany$] newest_in ./*
foo.txt
[rany$]
İlk olarak, -R
seçenek, tüm alt dizinlerde de arama yapacak olan, muhtemelen istediğiniz şey olmayan özyineleme içindir. İkinci olarak, <
operatör (yönlendirme olarak görülmediğinde) dize karşılaştırması içindir. Muhtemelen istiyorsun -lt
. Deneyin:
while [ `ls -1A | grep ^- | wc -l` -lt 3 ]
Ama burada bul kullanacağım:
while [ `find . -maxdepth 1 -type f -print | wc -l` -lt 3 ]
Ayrıştırmanın günah olduğunu biliyorum ls
, ama buna ne dersin:
find . -type f -maxdepth 1 | xargs ls -ltr | sed '1,3d' | awk '{print $9}' | xargs rm
5 boş dosyayla hızlı bir test:
$ >1
$ >2
$ >3
$ >4
$ >5
$ find . -type f -maxdepth 1 | xargs ls -lt | sed '1,3d' | awk '{print $9}' | xargs rm
$ ls -1
3
4
5
ls
çıkışını kullanarak find
ve xargs
yanlış şekilde bir araya. Eğer birleştirirseniz find
ve xargs
seni kullanımı tavsiye find
lar -print0
ve buna göre xargs
s -O
seçenekleri. Konu hakkında daha fazla bilgi için Bul özelliğini kullanma hakkında bilgi edinin. Ayrıca bir göz atmak ve neden ls ayrıştırma çok kötü hakkında okumak isteyebilirsiniz .
Bu tek astar düşündüğüm her şeyi yapıyor:
ls -t1 /home/user/test | tail -n +4 | xargs -I{} rm -- "{}"
İşte bir çözüm:
rm /appserver/webapplogs/$(ls -t1 /appserver/webapplogs/|tail -1)