2010-11-08 5 views
19
silmek için

Olası Çoğalt:
Delete all but the most recent X files in bashBash komut tüm ama son 5 dizinleri

Ben günlük artımlı yedeklerini oluşturmak için bir komut dosyası var ve tüm yedekleri ancak 5 son silmeniz gerekir.

 
drwxr-xr-x 4 root root 4096 Oct 29 01:10 2010-10-29 
drwxr-xr-x 4 root root 4096 Oct 30 01:10 2010-10-30 
drwxr-xr-x 4 root root 4096 Oct 31 01:10 2010-10-31 
drwxr-xr-x 4 root root 4096 Nov 1 01:10 2010-11-01 
drwxr-xr-x 4 root root 4096 Nov 2 01:10 2010-11-02 
drwxr-xr-x 4 root root 4096 Nov 3 01:10 2010-11-03 
drwxr-xr-x 4 root root 4096 Nov 4 01:10 2010-11-04 
drwxr-xr-x 4 root root 4096 Nov 5 01:10 2010-11-05 
drwxr-xr-x 4 root root 4096 Nov 6 01:10 2010-11-06 
drwxr-xr-x 4 root root 4096 Nov 7 01:10 2010-11-07 
drwxr-xr-x 4 root root 4096 Nov 8 01:10 2010-11-08 
:

Örneğin, bu klasörler

Ve sadece son 5 dizini korumalı ve diğerlerini silmem gerekir. Komut yürütme sonra ben sadece bu olması gerekir:

 
drwxr-xr-x 4 root root 4096 Nov 4 01:10 2010-11-04 
drwxr-xr-x 4 root root 4096 Nov 5 01:10 2010-11-05 
drwxr-xr-x 4 root root 4096 Nov 6 01:10 2010-11-06 
drwxr-xr-x 4 root root 4096 Nov 7 01:10 2010-11-07 
drwxr-xr-x 4 root root 4096 Nov 8 01:10 2010-11-08 

5 gün önceki silmenize gerek yok, ben şimdi kullanıyorum bütün hariç 5 son dizinleri :)

silmeniz gerekir :

find /backup/increment -maxdepth 1 -type d -mtime +5 -exec rm -rf {} \;

Ama zamanla dayanmayan iyileştirilmiş gerek :)

DÜZENLEME: Bu, tüm günlerde yedeklemeler yapan bir sunucu için bir örnektir, ancak son 5'in öncesindeki tüm klasörleri silen bir komut dosyasına ihtiyacım var çünkü bilgisayarım gece saat 00: 10'da yedekleme yapıyor, ancak tüm geceler yedeklemenin yapılmadığından bilgisayarım tüm günler çalışmıyor ve her zaman son 5 yedeklerini :)

+0

, "Son 5" tutarındaki tanımı nedir? –

+0

@dogbane teşekkürler ama @MartinStettner çözümü daha zarif bir çözüm gibi görünüyor :) – Lito

+0

@David Ana yazıya bir yorum eklendi. – Lito

cevap

32

n inci hattı ile başlayan baskı hatlarına tail komutunu kullanın (Seçenek -n +N):

rm `ls -t | tail -n +6` 

Gerçekten naif çözüm, geçici bir dosya kullanarak, bu şekilde gidebilir Geçerli dizini zamana göre sıralar.

ls -t. tail -n +6, 6. satırdan başlayarak satırları alır. Backticks ile yapılan alıntı, borunun sonucunu rm komutuna besler.

rm `ls -t1 | head -n 5` 

ls -t zaman kriteri geçerli dizin verir:

eski ÇÖZÜM, doğru olmayan ...

bir çıkış ilk N hatları yazdırır head komutunu kullanın . head -n 5, önceki çıkışın ilk beş girişini alır. Backticks ile yapılan alıntı, borunun sonucunu rm komutuna besler. o "Zaman merkezli" değilse

ilk veriyi :) yaşamayı uygulamadan önce dışarı deneyin ...

+1

Bunun yerine * son * n satırları için kuyruk kullanmak istersiniz. Ama evet, bu çözüm benimkinden daha basit ve daha iyi. :) –

+1

Ne hakkında: 'rm $ (ls | sort -r | sed 1,5d)'; isimleri tarih sırasına göre sıralayın; onları ters sıraya göre sırala (en son önce); ilk beş satırı siliniz; ne olursa olsun kaldır. –

+0

@Max: Hatamı işaret ettiğin için teşekkürler. Neyse ki, '' tail' için + N seçeneği var (ki bundan haberdar değildim), bu yüzden tüm satırları alabiliriz * ama ilk n *. – MartinStettner

0

touch -t 1010290000 before 
touch -t 2011042359 after 

2 arasındaki tüm dosyaları bulmak başlangıç ​​ve bitiş tarihine sahip iki kukla dosyaları oluşturmak olmalı kukla dosyaları ve "rm -rf" sonuç

find . -newer before \! -newer after -exec rm -rf {} \; 
+0

Daha şık bir çözüm mü? :) – Lito

+0

Çözüm tarih/zamana dayalı olmayacaktır :) – Lito

1

bana göre. Zarif değil:

a=0; 
for i in `ls -t`; 
do 
    a=`expr $a + 1`; 
    if [ $a -gt 5 ]; then 
      echo "removing $i"; 
      rm -rf $i 
    fi; 
done 
+0

Bu zarif değil, ama olası bir çözümdür :) – Lito

0

ls -tr | perl -ne '{@files = <>; print @files [0 .. $ # files-5]} '| xargs -n1 echo rm -rf

Çalışmak için rm -rf'den önce ekoyu çıkarırsınız.

0

Hile, en yeniden en eskiye doğru değişiklik zamanına göre sıralanan ls seçeneğidir.

ls -t > /tmp/file_list 
num_files_to_keep=5 
# wc -l gets the line count of a file 
# first word of wc output is the actual line count, and that's all we need, so 
# delete everything after the space. 
num_files=`wc -l /tmp/file_list | sed "s/ .*//"` 
#if appropriate you should add a check for num_files < num_files_to_keep 
num_files_to_delete=$(($num_files - $num_files_to_keep)) 
rm `tail -n $num_files_to_delete /tmp/file_list`