2011-01-02 10 views
1

Meine IM speichert die Protokolle entsprechend dem Kontaktnamen. Ich habe eine Datei mit der Liste der aktiven Kontakte erstellt. Mein Problem ist folgendes:Entfernen alter Verzeichnisse mit Protokollen

Ich möchte ein Bash-Skript mit lesen die aktiven Kontakte Namen aus der Datei und vergleichen Sie es mit den Verzeichnissen. Wenn der Verzeichnisname nicht in der Liste gefunden würde, würde er in ein anderes Verzeichnis verschoben (nennen wir es "Archiv"). Ich versuche es für dich zu visualisieren.

  • Inhalt der Liste:

contact1
contact2

  • Inhalt der dir

contact1
contact2
CONTACT3
contact4

  • nach der Skript ausgeführt wird, wird der Inhalt fo der dir:

contact1
contact2

CONTACT3 ==> ../archive
contact4 ==>. ./archive

Antwort

0

Dies ist eine verbesserte Version der Antwort des marcog. Beachten Sie, dass das assoziative Array Bash 4 erfordert.

#!/bin/bash 
sourcedir=/path/to/foo 
destdir=/path/to/archive 
contactfile=/path/to/list 

declare -A contacts 

while read -r contact 
do 
    contacts[$contact]=1 
done < "$contactfile" 

for contact in "$sourcedir"/* 
do 
    if [[ -f $contact ]] 
    then 
     index=${contact##*/} 
     if [[ ! ${contacts[$index]} ]] 
     then 
      mv "$contact" "$destdir" 
     fi 
    fi 
done 

Edit:

Wenn Sie Verzeichnisse anstelle von Dateien in Bewegung sind, dann die for Schleife oben wie folgt aussehen ändern:

for contact in "$sourcedir"/*/ 
do 
    index=${contact/%\/} 
    index=${index##*/} 
    if [[ ! ${contacts[$index]} ]] 
    then 
     mv "$contact" "$destdir" 
    fi 
done 
+0

@Denis ... tut mir leid, funktioniert aber auch nicht. Ich fügte einen "Echotest" Zeilen in jedem Teil in Schleifen hinzu. Es scheint, dass keine "wenn ist" innerhalb der "für Kontakt in" $ sourcedir "/ * do" Schleife zu arbeiten – Mcgiwer

+0

@Mcgiwer: Das würde darauf hinweisen, dass alle Einträge in "$ Sourcedir" sind Verzeichnisse und keine sind normale Dateien. Wenn dies Verzeichnisse sind, die Sie verschieben möchten, finden Sie in meiner bearbeiteten Antwort eine entsprechende Version. –

+0

scheint es, dass der editierte funktioniert hat. Vielen Dank – Mcgiwer

0

Es könnte eine prägnantere Lösung geben, aber das funktioniert. Ich würde dringend empfehlen, die mv mit echo vorzuschreiben, um es zuerst zu testen, sonst könnte Sie mit einem ernsten Durcheinander enden, wenn es nicht tut, was Sie wollen.

declare -A contacts 
for contact in "[email protected]" 
do 
    contacts[$contact]=1 
done 
ls a | while read contact 
do 
    if [[ ! ${contacts[$contact]} ]] 
    then 
    mv "a/$contact" ../archive 
    fi 
done 
+0

Funktioniert das auch, wenn einer Die Namen der Kontakte beinhalten Leerzeichen oder Leerzeichen. spezielle Charaktere? – philonous

+0

@philonous Nein, ich werde das reparieren. Ich habe auch bemerkt, dass ich die Frage falsch gelesen habe, damit ich das auch beheben kann. – marcog

+1

Korrigiert, es behandelt Leerzeichen in Dateinamen, schlägt jedoch fehl, wenn der Name doppelte Anführungszeichen enthält. Ich bin mir nicht sicher, wie Sie das beheben würden. – marcog

1

Sie so etwas wie dies nutzen könnten:

mv $(ls | grep -v -x -F -f ../file.txt) ../archive 

Wo ../file.txt die Namen der Verzeichnisse enthält, die nicht bewegt werden sollte. Es wird hier angenommen, dass das aktuelle Verzeichnis nur Verzeichnisse enthält. Wenn das nicht der Fall ist, sollte ls durch etwas anderes ersetzt werden. Beachten Sie, dass der Befehl fehlschlägt, wenn keine Verzeichnisse vorhanden sind, die verschoben werden sollen.

Da in den Kommentaren der anderen Antwort, die Sie feststellen, dass Verzeichnisse mit Leerzeichen im Namen auftreten können, können Sie dies durch ersetzen:

for i in * 
do 
    echo $i | grep -v -x -q -F -f ../file.txt && mv "$i" ../archive 
done 
+0

+1 Schöne Antwort! Ich wusste, dass es eine präzisere Antwort geben muss. – marcog

Verwandte Themen