GNU/Linux >> Belajar Linux >  >> Linux

Hapus semua file kecuali 3 terbaru dalam skrip bash

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 di while loop menghapus mtime (tidak diperlukan lagi setelah sort selesai).
  • read kedua di while 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 memanggil rm dengan.

Linux
  1. 3 Cara Menghapus Semua File di Direktori Kecuali Satu atau Beberapa File dengan Ekstensi

  2. Sed:Hapus Semua Kemunculan String Kecuali Yang Pertama?

  3. Hapus Semua File Dalam Satu Folder Kecuali Yang Terakhir (Terbaru) 20?

  1. Hapus File Log Lama Kecuali Yang Terakhir (Diurutkan Secara Alfanumerik)?

  2. Dapatkan Semua File Tapi File Dalam Array – Bash?

  3. Bagaimana menemukan semua file yang jarang di Linux

  1. Pindahkan semua file kecuali satu

  2. Cara gzip semua file di semua sub-direktori di bash

  3. Transfer file menggunakan lftp dalam skrip bash