Antworten:
cd <the directory you want>
find . -type f ! -iname "*.pdf" -delete
.pdfDateiname endenWenn sich beispielsweise ein Verzeichnis tempin 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 .pdfam Ende genommen werden. -type fWählt nur Dateien aus, keine Verzeichnisse. -deletebedeutet, es zu löschen.
!muss vorher kommen -name. wird einfach -namenur einschließen .pdf, während -inamebeide .pdfund einschließen.PDFUm 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 .pdfam Ende. -deletebedeutet, es zu löschen. bin ich jetzt klar
-maxdepth 1Parameter enthalten haben, um mit zu beginnen. Dann schlagen Sie vor, den Parameter zu entfernen, falls rekursiv gelöscht werden soll.
-inameanstelle von verwenden sollten -name, oder Dateien mit .PDFeiner Erweiterung werden durchrutschen.
Mit bashder erweiterten Shell-Globbing-Funktion können Sie alle Dateien mit anderen als den .pdfverwendeten 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) rmBefehl, was zu einem Fehler wie
rm: cannot remove `*.!(pdf)': No such file or directory
Sie können dieses Standardverhalten mit der nullglobShell-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 mvBefehl (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 rmusing xargs. Zum Beispiel:
ls zeigt mir allesls | grep pdfZeigt mir die Dateien, die ich behalten möchte. Hmm.ls | grep -v pdfzeigt 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 rmsendet genau diese Liste zum rmLöschen anWie gesagt, ich mag dies hauptsächlich aus Sicherheitsgründen: kein Zufall rm *für mich. Zwei weitere Vorteile:
lsoder 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 awkoder was auch immer. Wenn Sie nur Dateien löschen müssen, deren Namen eine Farbe enthalten, können Sie diese auf dieselbe Weise aufbauen.findfinden und rmzu entfernen, anstatt mich daran erinnern zu müssen, dass findeine -deleteFlagge akzeptiert wird . Und wenn Sie dies erneut tun, können Sie alternative Lösungen erstellen. Vielleicht können Sie stattdessen rmeinen trashBefehl erstellen , der die Datei in den Papierkorb verschiebt (undeletion zulässt) und stattdessen an diesen weiterleitet rm. Sie brauchen keine findUnterstü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.zipusw. zu behandeln.
pdfirgendwo 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 lsErsetzen 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 -20zumindest überprüfen, ob sie ungefähr korrekt aussehen, und wenn Sie dies nur rm my_patterntun, 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 findoder 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 fileBefehls.
$ 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 forBefehls ist es, die Dateien im aktuellen Verzeichnis in Form von Variablen anzugeben $var. if-thenBefehl gibt die Namen von PDF-Dateien aus, indem er den Exit-Status 0von file -i "$var" | grep -q 'application/pdf\;'Befehl annimmt. Er gibt den Exit-Status von 0nur 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}')
-imit grepfür Groß- und Kleinschreibung Matching.
rm -i -- !(*@(a|x).pdf)
Lesen Sie als, entfernen Sie alle Dateien, die nicht a.pdfoder 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 aoder xMuster vor dem .pdfSuffix. 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 bashExtended 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. lsist ä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"-namebedeutet, dass Sie durch einen Namensparameter ausschließen möchten, und ist dann-deletedie Aktion, die beim Auffinden durchzuführen ist? Also sucht es nach allem außer "* .pdf" und löscht sie? Oder habe ich falsch verstanden?