Wie kann ich einige Dateien vom Dateinamenerweiterungsmechanismus in Bash ausschließen?

14

Ich habe Ubuntu-Dateisystemverzeichnisse im Stammverzeichnis und ich habe versehentlich Hunderte von Dateien in das Stammverzeichnis kopiert.

Ich habe intuitiv versucht, kopierte Dateien durch Ausschließen von Dateisystem wie zu entfernen

rm -rf !{bin,sbin,usr,opt,lib,var,etc,srv,libx32,lib64,run,boot,proc,sys,dev} ./.

Aber es funktioniert nicht. Wie lassen sich einige Verzeichnisse beim Löschen des gesamten Verzeichnisses ordnungsgemäß ausschließen?

BEARBEITEN: Versuchen Sie niemals einen der Befehle hier, ohne zu wissen, was zu tun ist!

kenn
quelle
1
Welche Shell benutzt du? Filename Globbing ist Shell-abhängig, wenn es darum geht, solche ausgefallenen Sachen zu machen.
Kusalananda
2
Keine Antwort, aber ich würde zum Beispiel verwenden mc. Wählen Sie alles mit *und deaktivieren Sie dann bestimmte Dateien mit -oder Insert.
pbm
1
Kannst du erklären, was 'mc' ist?
MikeP
@ Kusalananda es ist/bin/bash
kenn
3
@ MikeP: mcist Midnight Commander, eine sehr nützliche Nachahmung von Norton Commander. Es läuft in einem Terminal. (Sowohl Midnight Commander als auch Norton Commander sind Beispiele für einen so genannten orthodoxen Dateimanager .)
AlexP

Antworten:

21

Da Sie verwenden bash:

shopt -s extglob
echo rm -rf ./!(bin|sbin|usr|...)

Ich empfehle, echoam Anfang der Befehlszeile etwas hinzuzufügen , was möglicherweise das gesamte System in die Luft jagen kann. Entfernen Sie es, wenn Sie mit dem Ergebnis zufrieden sind.

Hinweis: Der obige Befehl entfernt keine versteckten Dateien (die Namen beginnen mit einem Punkt). Wenn Sie diese auch entfernen möchten, aktivieren Sie auch die dotglobOption:

shopt -s dotglob
jimmij
quelle
Ich habe es benutzt, um das Dateisystem erfolgreich zu bereinigen. Zuerst habe ich es in einem Verzeichnis getestet. Ich habe auch versucht, durch rm -rf ./!(bin,sbin,..)Kommas zu trennen, aber es werden alle Verzeichnisse entfernt.
Kenn
Was ist das für eine !(...)Syntax? Aus dem Beispiel habe ich intuitiv gedacht, ls ./!(*/)dass nur Dateien aufgelistet werden, aber es funktioniert nicht so.
giusti
@giusti Bei dieser Syntax handelt es sich um eine erweiterte Mustererkennung für den Dateinamenerweiterungsmechanismus. Die Beschreibung finden Sie im Handbuch zur Bash unter Pfadnamenerweiterung. Es kann nicht verwendet werden, um Dateitypen, nur Namen, auszuschließen, genau wie bei Sternchen *oder anderen Globs.
Jimmy
12

Dieser Befehl zeigt alle Nicht-Verzeichnisse in /:

find / -maxdepth 1 -type f

Sobald Sie absolut sicher sind, dass keine Dateien vorhanden sind, die Sie behalten möchten, können Sie Folgendes verwenden:

find / -maxdepth 1 -type f -delete

Sicherer wäre es, sie an einen anderen Ort zu verschieben, um sicherzustellen, dass Sie nicht etwas löschen, das Sie beibehalten möchten:

mkdir /root/preserve
find / -maxdepth 1 -type f -exec mv -- "{}" /root/preserve/\;

Wenn zusätzlich zu Dateien, Sie haben auch Verzeichnisse , dass Sie an die Wurzel des Dateisystems hinzugefügt haben, dies könnte durch automatisiert werden mit Ausnahme der LSB - Verzeichnisse von einem automatisierten mvoder rm, aber ehrlich gesagt, da wir es zu tun mit dem Spülen Dinge in der root des Dateisystems, würde ich empfehlen, dass Sie es manuell tun, wenn überhaupt möglich.

Wenn dies nicht machbar ist, könnte so etwas den Trick machen:

#!/bin/bash
declare -a excludes
for item in root sys 'lost+found' mnt home proc etc opt boot lib lib64 libx32 sbin media srv dev var usr bin tmp run; do
    excludes+=("$item")
done
if ! [[ -d /root/preserve ]]; then
    mkdir -p /root/preserve
fi
IFS="\n"
for item in find / -type d -maxdepth 1; do
    really=true
    for exclude in ${excludes[@]}; do
        if [[ "$exclude" == "${item#/}" ]]; then
            really=false
        fi
    done
    if [[ "true" == "$really" ]]; then
        mv -- "$item" /root/preserve/
    fi
done

Sobald Sie den Schreitest bestanden haben (dh Ihr System läuft noch und Sie schreien nicht vor Angst), können Sie den Inhalt von entfernen /root/preserve/.

Wichtiger Hinweis: Was auch immer Sie tun, denken Sie nicht einmal daran, eine Permutation von auszuführen rm -fr [ANYTHING GOES HERE] /.

DopeGhoti
quelle
Ihre Lösung löscht nur Dateien, aber es gibt auch Ordner.
Kenn
1
Einmal zu oft habe ich Schreie der Bestürzung von einem schlecht zielenden gehört rm. Wie ein Skript mit rm -fr $somepath/mit somepathdarin nicht initialisiert. Ich hätte noch weiter gehen können, um auszudrücken, wie ernst das ist, aber ich entschied mich, in meiner Ermahnung familienfreundlich zu bleiben.
DopeGhoti
3

Dies sollte die Arbeit erledigen (wenn auch nicht auf die gleiche Weise, wie es das OP verlangt):

ls -1 >1.txt
pico 1.txt 

Entfernen Sie alle Dateien / Verzeichnisse, die Sie behalten möchten

xargs rm < 1.txt

Wenn Ihre Dateien alle dasselbe Namensformat, Datum oder etwas anderes haben, gibt es andere Methoden.

Ich würde mir die Inodes ansehen - und sehen, ob sie über ls -i | sort sequentiell sind, und wenn ja, dann werden die neuen Dateien größere Inodes haben. Dann mit der gleichen Art von Prozess wie oben ...

ls -iF1 | sort |cut -c10- | grep -vE "\/|\@" >i.txt   #This part removes entries that are not regular files, such as directories and links.  
pico i.txt
xargs rm < i.txt

Überprüfen Sie im obigen Befehl "Ausschneiden" zuerst Ihre Inodes-Liste, um sicherzustellen, dass es sich um die richtige Menge handelt.

MikeP
quelle