Script shell untuk menghapus direktori yang lebih lama dari n hari

165

Saya memiliki direktori bernama:

2012-12-12
2012-10-12
2012-08-08

Bagaimana cara saya menghapus direktori yang lebih dari 10 hari dengan skrip bash shell?

bobsr
sumber
1
Untuk mereka telanjang hubungan pada waktu penciptaan / modifikasi yang sebenarnya? Karena findbisa melakukannya tanpa melihat nama itu ...
Wrikken
mereka juga harus memiliki waktu kreasi / modifikasi
bobsr
4
Apa yang Anda maksud dengan "lebih tua dari"? Apakah Anda mengacu pada waktu direktori itu dibuat, waktu isinya terakhir diubah, atau sesuatu yang lain? Hati-hati dengan beberapa jawaban di bawah ini; ctimeadalah waktu perubahan inode. Untuk direktori, itu berubah ketika file ditambahkan atau dihapus dari direktori.
ajk

Jawaban:

390

Ini akan melakukannya secara rekursif untuk Anda:

find /path/to/base/dir/* -type d -ctime +10 -exec rm -rf {} \;

Penjelasan:

  • find: perintah unix untuk mencari file / direktori / tautan dll.
  • /path/to/base/dir: direktori untuk memulai pencarian Anda.
  • -type d: hanya menemukan direktori
  • -ctime +10: hanya pertimbangkan yang modifikasi waktu lebih dari 10 hari
  • -exec ... \;: untuk setiap hasil yang ditemukan, lakukan perintah berikut di ...
  • rm -rf {}: secara rekursif menghapus direktori; yang {}bagian mana hasil find akan diganti menjadi dari bagian sebelumnya.

Atau, gunakan:

find /path/to/base/dir/* -type d -ctime +10 | xargs rm -rf

Yang sedikit lebih efisien, karena berjumlah:

rm -rf dir1 dir2 dir3 ...

sebagai lawan:

rm -rf dir1; rm -rf dir2; rm -rf dir3; ...

seperti pada -execmetode.


Dengan versi modern find, Anda dapat mengganti ;dengan +dan itu akan melakukan yang setara dengan xargspanggilan untuk Anda, meneruskan file sebanyak yang sesuai pada setiap panggilan sistem exec:

find . -type d -ctime +10 -exec rm -rf {} +
sampson-chen
sumber
12
-mtimelebih baik bagi saya karena memeriksa perubahan konten daripada perubahan izin, jika tidak, ini sempurna.
quickshiftin pada
7
saya pikir ini juga akan menghapus dir base itu sendiri
Atau Gal
3
@ OrGal Anda benar-benar benar. Untuk mencegah ini, hanya menggunakan: find /path/to/base/dir/*.
zloynemec
11
Anda dapat menggunakan -maxdepth 1 untuk mengabaikan isi direktori
Sam
7
Pendekatan yang lebih efisien dapat menjadi bumerang jika Anda memiliki terlalu banyak folder untuk dihapus: stackoverflow.com/questions/11289551/… . Untuk alasan yang sama, untuk menghindari penghapusan folder dasar lebih baik digunakan -mindepth 1(daripada /path/to/folder/*).
Ohad Schneider
41

Jika Anda ingin menghapus semua subdirektori di bawah /path/to/base, misalnya

/path/to/base/dir1
/path/to/base/dir2
/path/to/base/dir3

tetapi Anda tidak ingin menghapus root /path/to/base, Anda harus menambahkan -mindepth 1dan -maxdepth 1opsi, yang akan mengakses hanya subdirektori di bawah/path/to/base

-mindepth 1mengecualikan root /path/to/basedari pertandingan.

-maxdepth 1akan HANYA mencocokkan subdirektori langsung di bawah /path/to/baseseperti /path/to/base/dir1, /path/to/base/dir2dan /path/to/base/dir3tetapi tidak akan mendaftar subdirektori ini secara rekursif. Jadi, subdirektori contoh ini tidak akan dicantumkan:

/path/to/base/dir1/dir1
/path/to/base/dir2/dir1
/path/to/base/dir3/dir1

Dan seterusnya.

Jadi, untuk menghapus semua sub-direktori /path/to/baseyang lebih dari 10 hari;

find /path/to/base -mindepth 1 -maxdepth 1 -type d -ctime +10 | xargs rm -rf
pmgarvey
sumber
19

findmendukung -deleteoperasi, jadi:

find /base/dir/* -ctime +10 -delete;

Saya pikir ada menangkap bahwa file harus lebih dari 10 hari juga. Belum mencoba, seseorang dapat mengonfirmasi dalam komentar.

Solusi yang paling banyak dipilih di sini tidak ada -maxdepth 0sehingga akan memanggil rm -rfuntuk setiap subdirektori, setelah menghapusnya. Itu tidak masuk akal, jadi saya sarankan:

find /base/dir/* -maxdepth 0  -type d -ctime +10 -exec rm -rf {} \;

The -deletesolusi di atas tidak menggunakan -maxdepth 0karena findakan mengeluh dir tidak kosong. Sebaliknya, ini menyiratkan -depthdan menghapus dari bawah ke atas.

Ondra Žižka
sumber
Saya dapat mengkonfirmasi -deletepekerjaan, tetapi seperti yang Anda katakan, Anda hanya dapat menggunakannya untuk menghapus direktori kosong, seperti rmdir.
CTodea
3

Saya berjuang untuk memperbaiki ini menggunakan skrip yang disediakan di atas dan beberapa skrip lainnya terutama ketika file dan nama folder memiliki baris atau spasi baru.

Akhirnya menemukan tmpreaper dan telah bekerja dengan baik untuk kami sejauh ini.

tmpreaper -t 5d ~/Downloads


tmpreaper  --protect '*.c' -t 5h ~/my_prg

Tautan Sumber asli

Memiliki fitur seperti tes, yang memeriksa direktori secara rekursif dan daftar mereka. Kemampuan untuk menghapus symlink, file atau direktori dan juga mode perlindungan untuk pola tertentu saat menghapus

user_v
sumber
2

ATAU

rm -rf `find /path/to/base/dir/* -type d -mtime +10`

Versi yang diperbarui dan lebih cepat:

find /path/to/base/dir/* -mtime +10 -print0 | xargs -0 rm -f
Luar biasa
sumber
2
Yang ini bisa dengan mudah melebihi panjang baris perintah maksimum. Lihat xargs --show-limits.
Michael Krupp
2
Juga tidak akan berfungsi jika ada nama file yang mengandung spasi atau karakter shell khusus lainnya.
Martin Tournoij
@Carpetsmoker Bukankah -print0/ -0merawat karakter shell khusus, atau tidak?
mpen
Anda benar bahwa xargsversi akan @mpen, tetapi baris pertama tidak akan.
Martin Tournoij