Jawaban:
Jika Anda ingin mengulang file, jangan pernah gunakanls
*. tl; dr Ada banyak situasi di mana Anda akhirnya akan menghapus file yang salah, atau bahkan semua file.
Yang mengatakan, sayangnya ini adalah hal yang rumit untuk dilakukan dengan benar di Bash. Ada jawaban yang bekerja lebih di sebuah pertanyaan duplikat saya bahkan lebih tuafind_date_sorted
yang dapat Anda gunakan dengan modifikasi kecil:
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
* Jangan tersinggung guys - Saya juga pernah menggunakan ls
sebelumnya. Tapi itu sebenarnya tidak aman.
Sunting: Barufind_date_sorted
dengan unit test.
((++counter>3))
sebagai ujian Anda. Sangat ringkas. Adapun oneliners: Jika singkatnya perhatian membungkus kode dalam suatu fungsi, maka jangan khawatir tentang hal itu.
Untuk menghapus semua kecuali 3 file terbaru menggunakan zsh glob, Anda dapat menggunakan Om
( huruf besar O) untuk mengurutkan file dari yang terlama ke yang terbaru dan subskrip untuk mengambil file yang Anda inginkan.
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
Contoh lain:
# 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])
Sejauh ini, metode yang paling mudah adalah menggunakan zsh dan kualifikasi globalnya : Om
untuk mengurutkan berdasarkan usia yang lebih tua (yaitu yang terlama lebih dulu) dan [1,3]
hanya mempertahankan tiga pertandingan pertama.
rm ./*(Om[1,3])
Lihat juga Bagaimana cara memfilter gumpalan di zsh untuk contoh lebih lanjut.
Dan perhatikan saran l0b0 : kode Anda akan rusak parah jika Anda memiliki nama file yang berisi karakter khusus shell.
Anda dapat menggunakan fungsi berikut untuk mendapatkan file terbaru di direktori:
newest_in()
{
local newest=$1
for f;do [[ $f -nt $newest ]] && newest="$f"; done;
printf '%s\n' "$newest"
}
Berikan satu set file berbeda dengan mengeluarkan file terbaru setelah setiap iterasi.
Kiat: Jika Anda memegang set file awal dalam array yang disebut "$ {files [@]}", maka simpan indeks file terbaru yang ditemukan, dan unset 'files[index]'
sebelum iterasi berikutnya.
Pemakaian: newest_in [set of files/directories]
Output sampel:
[rany$] newest_in ./*
foo.txt
[rany$]
Pertama, -R
opsi untuk rekursi, yang mungkin bukan yang Anda inginkan - yang akan mencari di semua subdirektori juga. Kedua, <
operator (ketika tidak dilihat sebagai pengalihan) adalah untuk perbandingan string. Anda mungkin mau -lt
. Mencoba:
while [ `ls -1A | grep ^- | wc -l` -lt 3 ]
Tetapi saya akan menggunakan temukan di sini:
while [ `find . -maxdepth 1 -type f -print | wc -l` -lt 3 ]
Saya tahu itu dosa untuk diurai ls
, tetapi bagaimana dengan ini:
find . -type f -maxdepth 1 | xargs ls -ltr | sed '1,3d' | awk '{print $9}' | xargs rm
Tes cepat dengan 5 file kosong:
$ >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
output dan menggunakan find
dan xargs
bersama - sama dengan cara yang salah. Jika Anda menggabungkan find
dan xargs
saya sarankan Anda untuk menggunakan find
s -print0
dan sesuai xargs
s -O
pilihan. Baca tentang Menggunakan Temukan untuk informasi lebih lanjut tentang subjek. Anda mungkin juga ingin melihat dan membaca tentang mengapa Parsing sangat buruk.
Satu kalimat ini melakukan semua yang saya pikirkan:
ls -t1 /home/user/test | tail -n +4 | xargs -I{} rm -- "{}"
Inilah salah satu solusinya:
rm /appserver/webapplogs/$(ls -t1 /appserver/webapplogs/|tail -1)