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 -zmelakukan pengurutan numerik umum (floating-point, bukan bilangan bulat) berdasarkan kolom pertama (waktu) dengan garis yang dipisahkan oleh NUL.readpertama diwhileloop menghapus mtime (tidak diperlukan lagi setelahsortselesai).readkedua diwhileloop 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 -0kemudian tambahkan nama file itu ke dalam daftar argv yang dikumpulkannya untuk memanggilrmdengan.