it-swarm.com.de

Entfernen Sie alle Dateien / Verzeichnisse mit Ausnahme einer Datei

Ich habe ein Verzeichnis mit einer großen Anzahl von Dateien. Ich möchte alle Dateien außer file.txt löschen. Wie mache ich das?

Es gibt zu viele Dateien, um die unerwünschten Dateien einzeln zu entfernen, und ihre Namen sind zu unterschiedlich, um sie zu verwenden *, um sie alle außer dieser einen Datei zu entfernen.

Jemand schlug vor, zu verwenden

rm !(file.txt)

Aber es funktioniert nicht. Es gibt zurück:

Badly placed ()'s 

Mein Betriebssystem ist Scientific Linux 6.

Irgendwelche Ideen?

275
Kantura

POSIXly:

find . ! -name 'file.txt' -type f -exec rm -f {} +

entfernt alle regulären Dateien (rekursiv, einschließlich versteckter) mit Ausnahme von file.txt. Um Verzeichnisse zu entfernen, ändern Sie -type f In -type d Und fügen Sie die Option -r Zu rm hinzu.

In bash müssen Sie extglob aktivieren, um rm -- !(file.txt) zu verwenden:

$ shopt -s extglob 
$ rm -- !(file.txt)

(oder bash -O extglob aufrufen)

Beachten Sie, dass extglob nur in bash und der Korn Shell-Familie funktioniert. Die Verwendung von rm -- !(file.txt) kann einen Argument list too long - Fehler verursachen.

In zsh können Sie ^ Verwenden, um das Muster mit aktiviertem Extendedglob zu negieren:

$ setopt extendedglob
$ rm -- ^file.txt

oder verwenden Sie dieselbe Syntax mit ksh und bash mit aktivierten Optionen ksh_glob und no_bare_glob_qual.

323
cuonglm

Eine andere Einstellung in eine andere Richtung (wenn die Dateinamen keine Leerzeichen enthalten)

ls | grep -v file.txt | xargs rm

oder (funktioniert auch, wenn die Dateinamen Leerzeichen enthalten)

ls | grep -v file.txt | parallel rm

von man grep:

 -v, --invert-match
          Invert the sense of matching, to select non-matching lines.  (-v is specified by POSIX)
124
Sebastian

Eine Kopie pflegen, alles löschen, Kopie wiederherstellen:

{   rm -rf *
    tar -x
} <<TAR
$(tar -c $one_file)
TAR

In einer Zeile:

{ rm -rf *; tar -x; } <<< $(tar -c $one_file)

Dies erfordert jedoch eine Shell, die Here-Strings unterstützt.

35
mikeserv

sie alle denken darüber nach.

cd ..
mv fulldir/file.txt /tmp/
rm -rf fulldir
mkdir fulldir
mv /tmp/file.txt fulldir/

Erledigt.

EDIT Eigentlich einfacher:

cd ..
ln fulldir/file.txt ./
rm -rf fulldir
mkdir -p fulldir
mv file.txt fulldir/
26
Shadur

Auf meinem Scientific Linux 6-Betriebssystem funktioniert dies:

shopt -s extglob
rm !(file.txt)

Ich habe auch Debian 32bit auf einer virtuellen Maschine installiert. Das Obige funktioniert nicht, aber das Folgende funktioniert:

find . -type f ! -name 'file.txt' -delete
19
Kantura

Verwenden Sie rm !("file.txt") anstelle von rm !(file.txt)

12

Um eine andere Antwort zu geben, können Sie das Standardverhalten von rm verwenden, bei dem keine Ordner gelöscht werden:

mkdir tmp && mv file.txt tmp  # create tmp dir and move files there
rm                            # delete all other files
mv tmp/* . && rm -rf tmp      # move all files back and delete tmp dir
8
Nithin

Ich finde, dass dieser Ansatz sehr einfach ist, funktioniert und keine speziellen Erweiterungen erfordert (die ich kenne!).

ls --hide=file.txt | xargs rm
4
2-bits