Antworten:
cd <the directory you want>
find . -type f ! -iname "*.pdf" -delete
.pdf
Dateiname endenWenn sich beispielsweise ein Verzeichnis temp
in Ihrem privaten Ordner befindet, gehen Sie wie folgt vor :
cd ~/temp
dann Dateien löschen:
find . -type f ! -iname "*.pdf" -delete
Dadurch werden alle Dateien außer gelöscht xyz.pdf
.
Sie können diese beiden Befehle kombinieren, um:
find ~/temp -type f ! -iname "*.pdf" -delete
.
ist das aktuelle Verzeichnis. !
bedeutet, dass alle Dateien außer denen mit .pdf
am Ende genommen werden. -type f
Wählt nur Dateien aus, keine Verzeichnisse. -delete
bedeutet, es zu löschen.
!
muss vorher kommen -name
. wird einfach -name
nur einschließen .pdf
, während -iname
beide .pdf
und einschließen.PDF
Um nur im aktuellen Verzeichnis und nicht in den Unterverzeichnissen zu löschen, fügen Sie Folgendes hinzu -maxdepth 1
:
find . -maxdepth 1 -type f ! -iname "*.pdf" -delete
.
bedeutet aktuelles Verzeichnis. !
bedeutet, alle Dateien mit Ausnahme der .pdf
am Ende. -delete
bedeutet, es zu löschen. bin ich jetzt klar
-maxdepth 1
Parameter enthalten haben, um mit zu beginnen. Dann schlagen Sie vor, den Parameter zu entfernen, falls rekursiv gelöscht werden soll.
-iname
anstelle von verwenden sollten -name
, oder Dateien mit .PDF
einer Erweiterung werden durchrutschen.
Mit bash
der erweiterten Shell-Globbing-Funktion können Sie alle Dateien mit anderen als den .pdf
verwendeten Erweiterungen entfernen
rm -- *.!(pdf)
Wie von @pts angegeben, geben die --
Zeichen das Ende aller Befehlsoptionen an. Stellen Sie den Befehl in seltenen Fällen sicher, wenn die Namen der Dateien mit einem -
Zeichen beginnen.
Wenn Sie Dateien ohne oder mit einer anderen Erweiterung löschen möchten, können Sie .pdf
, wie von @DennisWilliamson ausgeführt, diese verwenden
rm -- !(*.pdf)
Erweitertes Globbing sollte standardmäßig aktiviert sein. Wenn dies nicht der Fall ist, können Sie dies mit tun
shopt -s extglob
Insbesondere wenn Sie dies in einem Skript verwenden möchten, ist es wichtig zu beachten, dass der Glob standardmäßig nicht erweitert an den übergeben wird, wenn der Ausdruck mit nichts übereinstimmt (dh wenn sich keine Nicht-PDF-Dateien im Verzeichnis befinden) rm
Befehl, was zu einem Fehler wie
rm: cannot remove `*.!(pdf)': No such file or directory
Sie können dieses Standardverhalten mit der nullglob
Shell-Option ändern, dies hat jedoch ein eigenes Problem. Eine ausführlichere Diskussion finden Sie in NullGlob - Gregs Wiki
rm *~*.pdf
!(*.py)
. Wenn das OP nur ".pdf" -Dateien übrig haben möchte, sollten vermutlich auch Dateien ohne Erweiterungen gelöscht und nicht ignoriert werden.
$ cd <the directory you want>
$ gvfs-trash !(*.pdf)
Oder über mv
Befehl (aber auf diese Weise können Sie es nicht aus dem Papierkorb wiederherstellen , da es nicht .trashinfo Informationen aufzeichnen, so dass diese Mittel Sie Ihre Dateien auf ein bewegtes Ziel , wo es ist , wie folgend).
mv !(*.pdf) ~/.local/share/Trash/files
rm
.
Der einfachste Ansatz: Erstellen Sie irgendwo ein anderes Verzeichnis (wenn Sie nur in einem Verzeichnis löschen, nicht rekursiv, kann es sogar ein Unterverzeichnis sein); Bewegen Sie alle PDFs dorthin. alles andere löschen; Schiebe die PDF's zurück; Zwischenverzeichnis löschen.
Schnell und einfach können Sie genau sehen, was Sie tun. Stellen Sie einfach sicher, dass sich das Zwischenverzeichnis auf demselben Gerät befindet wie das Verzeichnis, das Sie bereinigen, damit Verschiebungen Umbenennungen und keine Kopien sind!
Verwende bashs GLOBIGNORE:
GLOBIGNORE=x.pdf:a.pdf
rm *
unset GLOBIGNORE
Aus der Manpage von bash:
GLOBIGNORE: Eine durch Doppelpunkte getrennte Liste von Mustern, die die Menge definieren von Dateinamen, die von der Pfadnamenerweiterung ignoriert werden sollen.
Ein kurzer Test:
mkdir /tmp/foooooo
cd /tmp/foooooo
touch x.pdf y.zip z.mp3 a.pdf
GLOBIGNORE=x.pdf:a.pdf
ls -1 *
Ausgabe:
y.zip z.mp3
Hier ist ein Ansatz, den ich mag, da ich sehr vorsichtig sein kann: Erstelle einen Weg, um nur die Dateien anzuzeigen, die ich löschen möchte, und sende sie dann an rm
using xargs
. Zum Beispiel:
ls
zeigt mir allesls | grep pdf
Zeigt mir die Dateien, die ich behalten möchte. Hmm.ls | grep -v pdf
zeigt das gegenteil: alles ausser was ich behalten will. Mit anderen Worten, es wird die Liste der Dinge angezeigt, die ich löschen möchte. Ich kann das bestätigen, bevor ich etwas Gefährliches tue.ls | grep -v pdf | xargs rm
sendet genau diese Liste zum rm
Löschen anWie gesagt, ich mag dies hauptsächlich aus Sicherheitsgründen: kein Zufall rm *
für mich. Zwei weitere Vorteile:
ls
oder verwenden find
, um die anfängliche Liste zu erhalten. Sie können alles verwenden, was Sie möchten, um diese Liste einzugrenzen - eine andere grep
, eine andere awk
oder was auch immer. Wenn Sie nur Dateien löschen müssen, deren Namen eine Farbe enthalten, können Sie diese auf dieselbe Weise aufbauen.find
finden und rm
zu entfernen, anstatt mich daran erinnern zu müssen, dass find
eine -delete
Flagge akzeptiert wird . Und wenn Sie dies erneut tun, können Sie alternative Lösungen erstellen. Vielleicht können Sie stattdessen rm
einen trash
Befehl erstellen , der die Datei in den Papierkorb verschiebt (undeletion zulässt) und stattdessen an diesen weiterleitet rm
. Sie brauchen keine find
Unterstützung für diese Option, Sie leiten einfach zu ihr.In den Kommentaren von @pabouk finden Sie Informationen dazu, wie Sie dies ändern können, um einige Randfälle wie Zeilenumbrüche in Dateinamen, Dateinamen my_pdfs.zip
usw. zu behandeln.
pdf
irgendwo in ihrem Namen enthalten sind. --- b) Es werden PDF-Dateien gelöscht, wenn einer der Buchstaben im Suffix in Großbuchstaben geschrieben ist. --- c) Es ist keine gute Idee, die Ausgabe von zu verwenden ls
. Es funktioniert nicht mit Dateinamen, die Zeilenumbrüche enthalten. Einige Implementierungen zum ls
Ersetzen von Sonderzeichen, z ?
. B. tab durch . --- Es ist besser zu nutzen: find -maxdepth 1 -print0
. (nicht so kurz wie ls
:) ----- Um a) und b) zu lösen, verwenden Sie grep -vi '\.pdf$'
--- vollständige (aber nur GNU) Lösung:find -maxdepth 1 -print0 | grep -viz '\.pdf$' | xargs -0 rm
| head -20
zumindest überprüfen, ob sie ungefähr korrekt aussehen, und wenn Sie dies nur rm my_pattern
tun, haben Sie keine Chance, einen großen Fehler zu entdecken.
find . -type f ! -name "*.pdf"
, um auf die Konsole zu drucken oder auf less oder eine Datei umzuleiten . [und dann wie in Pabouks Kommentaren (mit -print0 | ... -0 für seltsame Dateinamen) an xargs rm weiterleiten]
Normalerweise löse ich solche Probleme mit dem interaktiven Python-Interpreter:
mic@mic ~ $ python
>>> import os
>>> for f in os.listdir('.'):
... if not f.endswith('.pdf'):
... os.remove(f)
Es mag länger sein als ein Einzeiler mit find
oder xargs
, aber es ist extrem belastbar, und ich weiß genau, was es tut, ohne es zuerst erforschen zu müssen.
for item in [f for f in os.listdir('.') if not f.endswith('.pdf')]: os.remove(item)
python -c "import os; for f in os.listdir('.'): if not f.endswith('.pdf'): os.remove(f)"
[os.remove(f) for f in os.listdir('.') if not f.endswith('.pdf')]
Eine bessere Antwort (im Vergleich zu meiner vorherigen Antwort) auf diese Frage ist die Verwendung des leistungsstarken file
Befehls.
$ file -i abc.pdf
abc: application/pdf; charset=binary
jetzt dein problem:
cd <the directory you want to search in>
for var in ./*
do
if file -i "$var" | grep -q 'application/pdf\;'
then
echo "$var"
fi
done
Die Aufgabe des for
Befehls ist es, die Dateien im aktuellen Verzeichnis in Form von Variablen anzugeben $var
. if-then
Befehl gibt die Namen von PDF-Dateien aus, indem er den Exit-Status 0
von file -i "$var" | grep -q 'application/pdf\;'
Befehl annimmt. Er gibt den Exit-Status von 0
nur dann an, wenn er PDF-Dateien findet.
rm $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')
Warnung! Versuchen Sie es lieber zuerst
ls -l $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')
-i
mit grep
für Groß- und Kleinschreibung Matching.
rm -i -- !(*@(a|x).pdf)
Lesen Sie als, entfernen Sie alle Dateien, die nicht a.pdf
oder sind x.pdf
.
Dies funktioniert durch die Verwendung von 2 erweitert Klackse machen, die äußere !()
die enthaltenen glob negieren , die selbst erfordert , dass die glob eine oder mehrere übereinstimmen müssen a
oder x
Muster vor dem .pdf
Suffix. Siehe glob # extglob .
$ ls -a
.dotfile1 .dotfile2 a.pdf x.pdf y.zip z.mp3
$ echo -- !(a.pdf)
-- x.pdf y.zip z.mp3
$ echo -- !(x.pdf)
-- a.pdf y.zip z.mp3
$ echo -- !(a.pdf|x.pdf)
-- y.zip z.mp3
$ echo -- !(@(a|x).pdf) # NOTE.that this matches the .dotfiles* as well
-- . .. .dotfile1 .dotfile2 y.zip z.mp3
$ echo -- !(*@(a|x).pdf) # but this doesn't
-- y.zip z.mp3
$ echo rm -i -- !(*@(a|x).pdf)
rm -i -- y.zip z.mp3
$ ksh -c 'for i in ./*; do case $i in *.pdf)continue;; *)rm "$i";; esac;done'
Ziemlich viel POSIX und kompatibel mit jedem Bourne-style - Shell ( ksh
, bash
, dash
). Gut geeignet für portable Skripte und wenn Sie das bash
Extended Shell Globbing nicht verwenden können .
$ perl -le 'opendir(my $d,"."); foreach my $f (grep(-f && !/.pdf/ , readdir($d))){unlink $f};closedir $d'
Oder etwas sauberer:
$ perl -le 'opendir(my $d,"."); map{ unlink $_ } grep(-f "./$_" && !/.pdf/ , readdir($d));closedir $d'
python -c 'import os;map(lambda x: os.remove(x), filter(lambda x: not x.endswith(".pdf"),os.listdir(".")))'
Pass auf, was du löschst!
Ein sicherer Weg, es zu testen, bevor Sie versuchen, es zu löschen, besteht darin, es zuerst mit zu testen ls
, da einige nicht erfasste Verhaltensweisen unerwünschte Dateien löschen könnten. Und Sie können dies direkt außerhalb des Verzeichnisses tun. ls
ist ähnlich wie rm
, so:
ls sub/path/to/files/!(*.pdf)
Dies wird aufgelistet
y.zip
z.mp3
Und jetzt können Sie sehen, was Sie löschen und sie sicher löschen:
rm sub/path/to/files/!(*.pdf)
Und das ist es. Sie können Platzhalter verwenden *
, um selektiver zu sein, wie z. B. nur Programmierunterlagen aufzubewahren:
rm sub/path/to/files/!(*programming*)
.
bedeutet "und"?!
bedeutet "Ausgenommen"-name
bedeutet, dass Sie durch einen Namensparameter ausschließen möchten, und ist dann-delete
die Aktion, die beim Auffinden durchzuführen ist? Also sucht es nach allem außer "* .pdf" und löscht sie? Oder habe ich falsch verstanden?