2008-09-16 7 views
4

Ich möchte alle bis auf die 4 neuesten Verzeichnisse in meinem Elternverzeichnis löschen. Wie würdest du das in Bash machen?Löschen Sie alle bis auf die 4 neuesten Verzeichnisse

+0

Sie können die Erstellungszeit von Dateien oder Verzeichnissen nicht abrufen, da sie nirgendwo gespeichert ist. Der nächste, den Sie bekommen können, ist die Inode Change Time: http://www.faqs.org/faqs/unix-faq/faq/part3/section-1.html und das Hinzufügen oder Entfernen von Dateien aus Verzeichnissen ändert den Inode. –

+0

... obwohl das Hinzufügen oder Entfernen von Dateien aus einem Child-Verzeichnis * keinen * Eltern-Inode ändert. –

Antwort

9
ls -atrd */ | head --lines=-4 | xargs rm -rf 

Edit: hinzugefügt ‚a‘ Argument

ls
+0

Dies wird 4 zuletzt geänderte Verzeichnisse anstelle der 4 zuletzt erstellten, nicht bemerken, Verzeichnisse beginnend mit einem Punkt, Kopf bricht für Namen, die Zeilenumbrüche, Xargs wird brechen für Namen, die Leerzeichen enthalten, und rm wird eine Fehlermeldung ausgeben wenn es nichts zu löschen gibt. –

+0

Gute Punkte. Ich habe jetzt 'a' zu ls hinzugefügt, um Verzeichnisse mit einem Punkt zu erfassen, und grepped, um die aktuellen und übergeordneten Verzeichnisse loszuwerden, aber Sie haben Recht. Dies ist eine einfache Antwort mit einigen wichtigen Einschränkungen, auf die Sie hingewiesen haben. –

+0

Korrektur: Es wird kein grep benötigt, um das aktuelle und das übergeordnete Verzeichnis zu filtern, da sie nicht durch ls * / –

1

Bitte klären Sie, wenn Sie „alle Verzeichnisse löschen, aber die vier newst ones“ bedeuten oder „alles (Dateien und Verzeichnisse) löschen, außer daß die vier neueste Verzeichnisse ".

Bitte beachten Sie auch, dass die Erstellungszeiten für Verzeichnisse nicht bekannt sind. Man kann nur feststellen, wann ein Verzeichnis zuletzt geändert wurde, das heißt, ob Dateien hinzugefügt, entfernt oder umbenannt wurden.

1

Sie könnte wie folgt vorgehen:

#!/bin/bash 

#store the listing of current directory in var 
mydir=`ls -t` 
it=1 

for file in $mydir 
    do 
     if [ $it -gt 5 ] 
     then 
      echo file $it will be deleted: $file 
      #rm -rf $file 
     fi 
     it=$((it+1)) 
    done 

(die # vor rm zu entfernen, um es wirklich geschehen;))

0

Ein weiterer, BSD-Safe, Art und Weise, es zu tun, mit Arrays (warum nicht?)

#!/bin/bash 
ARRAY=(`ls -td */`) 
ELEMENTS=${#ARRAY[@]} 
COUNTER=4 
while [ $COUNTER -lt $ELEMENTS ]; do 
    echo ${ARRAY[${COUNTER}]} 
    let COUNTER=COUNTER+1 
done 
Verwandte Themen