Solusi tanpa masalah dengan "ls" (file bernama aneh)
Ini adalah kombinasi dari jawaban ceving dan anubhava. Kedua solusi tersebut tidak bekerja untuk saya. Karena saya mencari skrip yang harus dijalankan setiap hari untuk mencadangkan file dalam arsip, saya ingin menghindari masalah dengan ls
(seseorang dapat menyimpan beberapa file bernama lucu di folder cadangan saya). Jadi saya memodifikasi solusi yang disebutkan agar sesuai dengan kebutuhan saya.
Solusi saya menghapus semua file, kecuali tiga file terbaru.
find . -type f -printf '%[email protected]\t%p\n' |
sort -t $'\t' -g |
head -n -3 |
cut -d $'\t' -f 2- |
xargs rm
Beberapa penjelasan:
find
daftar semua file (bukan direktori) di folder saat ini. Mereka dicetak dengan cap waktu.
sort
mengurutkan baris berdasarkan stempel waktu (terlama di atas).
head
mencetak baris teratas, hingga 3 baris terakhir.
cut
menghapus stempel waktu.
xargs
menjalankan rm
untuk setiap file yang dipilih.
Bagi Anda untuk memverifikasi solusi saya:
(
touch -d "6 days ago" test_6_days_old
touch -d "7 days ago" test_7_days_old
touch -d "8 days ago" test_8_days_old
touch -d "9 days ago" test_9_days_old
touch -d "10 days ago" test_10_days_old
)
Ini membuat 5 file dengan stempel waktu berbeda di folder saat ini. Jalankan skrip ini terlebih dahulu lalu kode untuk menghapus file lama.
Ini akan mencantumkan semua file kecuali tiga yang terbaru:
ls -t | tail -n +4
Ini akan menghapus file-file itu:
ls -t | tail -n +4 | xargs rm --
Ini juga akan mencantumkan file dot:
ls -At | tail -n +4
dan hapus dengan dotfiles:
ls -At | tail -n +4 | xargs rm --
Namun berhati-hatilah:parsing ls
bisa berbahaya jika nama file berisi karakter lucu seperti baris baru atau spasi. Jika Anda yakin bahwa nama file Anda tidak mengandung karakter lucu, parsing ls
cukup aman, terlebih lagi jika ini hanya skrip sekali pakai.
Jika Anda sedang mengembangkan skrip untuk penggunaan berulang maka Anda sebaiknya tidak mem-parsing output dari ls
dan gunakan metode yang dijelaskan di sini:http://mywiki.wooledge.org/ParsingLs
ls -t | tail -n +4 | xargs -I {} rm {}
Jika Anda menginginkan 1 liner
Berikut ini terlihat agak rumit, tetapi sangat hati-hati untuk menjadi benar, bahkan dengan nama file yang tidak biasa atau berbahaya. Sayangnya, ini membutuhkan alat GNU:
count=0
while IFS= read -r -d ' ' && IFS= read -r -d '' filename; do
(( ++count > 3 )) && printf '%s\0' "$filename"
done < <(find . -maxdepth 1 -type f -printf '%[email protected] %P\0' | sort -g -z) \
| xargs -0 rm -f --
Menjelaskan cara kerjanya:
- Cari memancarkan
<mtime> <filename><NUL>
untuk setiap file di direktori saat ini. sort -g -z
melakukan pengurutan numerik umum (floating-point, bukan bilangan bulat) berdasarkan kolom pertama (waktu) dengan garis yang dipisahkan oleh NUL.read
pertama diwhile
loop menghapus mtime (tidak diperlukan lagi setelahsort
selesai).read
kedua diwhile
loop membaca nama file (berjalan hingga NUL).- Perulangan bertambah, lalu memeriksa, penghitung; jika status penghitung menunjukkan bahwa kita melewati lompatan awal, maka kita mencetak nama file, dibatasi oleh NUL.
xargs -0
kemudian tambahkan nama file itu ke dalam daftar argv yang dikumpulkannya untuk memanggilrm
dengan.