it-swarm.com.de

 Verwenden von find - Löschen aller Dateien/Verzeichnisse (unter Linux) außer einem

Wenn wir alle von uns verwendeten Dateien und Verzeichnisse löschen möchten, rm -rf *.

Aber was ist, wenn alle Dateien und Verzeichnisse auf einmal gelöscht werden sollen, mit Ausnahme einer bestimmten Datei?

Gibt es einen Befehl dafür? rm -rf * erleichtert das Löschen auf einen Schlag, löscht aber sogar meine Lieblingsdatei/mein Lieblingsverzeichnis.

Danke im Voraus

14
kingsmasher1

find kann ein sehr guter Freund sein:

$ ls
a/  b/  c/
$ find * -maxdepth 0 -name 'b' -Prune -o -exec rm -rf '{}' ';'
$ ls
b/
$ 

Erläuterung:

  • find * -maxdepth 0: Wählen Sie alles aus, was von * ausgewählt wurde, ohne in ein Verzeichnis abzusteigen

  • -name 'b' -Prune: Störe (-Prune) nicht mit etwas, das der Bedingung entspricht -name 'b'

  • -o -exec rm -rf '{}' ';': Für alles andere rufen Sie rm -rf an

Übrigens wäre eine andere, möglicherweise einfachere Möglichkeit, das Verzeichnis favorite so zu verschieben oder umzubenennen, dass es nicht im Wege steht:

$ ls
a/  b/  c/
$ mv b .b
$ ls
a/  c/
$ rm -rf *
$ mv .b b
$ ls
b/
30
thkala

Kurze Antwort

ls | grep -v "z.txt" | xargs rm

Einzelheiten :

Der Denkprozess für den obigen Befehl ist:

  • Alle Dateien auflisten (ls)
  • Ignoriere eine Datei mit dem Namen "z.txt" (grep -v "z.txt")
  • Löschen Sie die aufgelisteten Dateien außer z.txt (xargs rm)

Beispiel

Erstellen Sie 5 Dateien wie folgt:

echo "a.txt b.txt c.txt d.txt z.txt" | xargs touch

Listet alle Dateien außer z.txt auf

ls|grep -v "z.txt"

a.txt
b.txt
c.txt
d.txt

Wir können nun die aufgelisteten Dateien mit dem Dienstprogramm xargs löschen (rm):

ls|grep -v "z.txt"|xargs rm
9
Thyag

Zumindest in zsh

rm -rf ^filename

dies kann eine Option sein, wenn Sie nur eine einzige Datei beibehalten möchten.

2
Inkane

Sie können es direkt in die Befehlszeile eingeben oder diesen Tastendruck im Skript verwenden

files=`ls -l | grep -v "my_favorite_dir"`; for file in $files; do rm -rvf $file; done

P.S. Ich schlage vor, -i für rm zu wechseln, um das Löschen wichtiger Daten zu verhindern.

PS: Sie können das auf dieser Lösung basierende kleine Skript schreiben und es in den /usr/bin (z. B. /usr/bin/rmf) einfügen. Jetzt können Sie es als normale App verwenden:

rmf my_favorite_dir

Das Skript sieht wie folgt aus (nur eine Skizze):

#!/bin/sh

if [[ -z $1 ]]; then
    files=`ls -l`
else
    files=`ls -l | grep -v $1`
fi;

for file in $files; do
    rm -rvi $file
done;
2
maverik

In bash haben Sie den Glob-Operator !(), der das übereinstimmende Muster invertiert. Versuchen Sie Folgendes, um alles außer der Datei my_file_name.txt zu löschen:

shopt -s extglob
rm -f !(my_file_name.txt)

Weitere Informationen finden Sie in diesem Artikel: http://karper.wordpress.com/2010/11/17/deleting-all-files-in-a-directory-with-exceptions/

1
chiborg

Wenn es sich nur um eine Datei handelt, besteht eine einfache Möglichkeit darin, diese Datei in /tmp oder so zu verschieben, rm -Rf das Verzeichnis und dann zurück zu verschieben. Sie können dies auch als einfachen Befehl bezeichnen.

Die andere Möglichkeit besteht darin, eine find und dann eine grep herauszufinden, was Sie nicht wollen (mit -v oder direkt mit einem der find-Prädikate) und dann die restlichen Dateien zu rmen.

Für eine einzelne Datei würde ich die erstere machen. Für alles andere würde ich eine Gewohnheit schreiben, die der von Thkala ähnelt.

1
Noufal Ibrahim
mv subdir/preciousfile  ./
rm -rf subdir
mkdir subdir
mv preciousfile subdir/

Das sieht mühsam aus, ist aber ziemlich sicher

  • vermeidet komplexe Logik
  • benutze niemals rm -rf *, die Ergebnisse hängen von deinem aktuellen Verzeichnis ab (das könnte / sein ;-)
  • verwenden Sie niemals einen globbing *: seine Erweiterung ist durch ARGV_MAX begrenzt.
  • ermöglicht es Ihnen, den Fehler nach jedem Befehl zu überprüfen und möglicherweise die durch den nächsten Befehl verursachte Katastrophe zu vermeiden.
  • vermeidet unangenehme Probleme, die durch Leerzeichen oder NL in den Dateinamen verursacht werden.
0
wildplasser
cd ..
ln trash/useful.file ./
rm -rf trash/*
mv useful.file trash/
0
Ivan

Ich kenne ein solches Programm nicht, aber ich habe es in der Vergangenheit schon einige Male gewollt. Die grundlegende Syntax wäre:

IFS='
' for f in $(except "*.c" "*.h" -- *); do
  printf '%s\n' "$f"
done

Das Programm, an das ich denke, hat drei Modi:

  • exakte Übereinstimmung (mit der Option -e)
  • glob matching (Standard, wie im obigen Beispiel gezeigt)
  • regex Matching (mit der Option -r)

Es dauert, bis die Muster von der Befehlszeile ausgeschlossen sind, gefolgt vom Trennzeichen --, gefolgt von den Dateinamen. Alternativ können die Dateinamen von stdin (wenn die Option -s angegeben ist) jeweils in einer Zeile gelesen werden.

Ein solches Programm sollte weder in C noch in der Shell-Befehlssprache schwer zu schreiben sein. Und es ist eine gute Übung zum Erlernen der Unix-Grundlagen. Wenn Sie es als Shell-Programm ausführen, müssen Sie natürlich auf Dateinamen achten, die Leerzeichen und andere Sonderzeichen enthalten.

0
Roland Illig

Ich sehe hier viele langwierige Mittel, die funktionieren, aber mit a/b/c/d/e /

 rm -rf *.* !(b*) 

dadurch wird alles außer dem Verzeichnis b/und seinem Inhalt entfernt (vorausgesetzt, Ihre Datei befindet sich in b /. Dann nur noch cd b/und

rm -rf *.* !(filename) 

entfernen Sie alles andere als die Datei (mit dem Namen "Dateiname"), die Sie behalten möchten.

0
tonybaldwin