Dateien rekursiv entfernen


140

Hat jemand eine Lösung, um diese lästigen ._- und .DS_Store-Dateien zu entfernen, die nach dem Verschieben von Dateien von einem Mac auf einen Linux-Server erhalten werden?

ein Startverzeichnis angeben und loslassen? wie / var / www / html / down ...


Obwohl es sich nicht um eine doppelte IMO handelt, sollten Sie sich Folgendes
ansehen

Obwohl nicht das, was Sie fragen. Ich würde argumentieren, dass dies eine bessere Lösung ist: unix.stackexchange.com/questions/9665/…
Viktor

Antworten:


169

Wechseln Sie in das Verzeichnis und verwenden Sie:

find . -name ".DS_Store" -print0 | xargs -0 rm -rf
find . -name "._*" -print0 | xargs -0 rm -rf

Nicht getestet, probieren Sie sie zuerst ohne die Xargs aus!

Sie können den Zeitraum nach dem Suchen durch das Verzeichnis ersetzen, anstatt zuerst in das Verzeichnis zu wechseln.

find /dir/here ...

2
Ich weiß, dass seine Frage nicht danach gefragt hat, aber ich kann mich nie erinnern: Behandelt Ihr Beispiel Dateinamen mit Leerzeichen?
Grundlefleck

4
Ja, dafür sind print0 und -0 to xargs gedacht. Normalerweise werden Leerzeichen nicht korrekt behandelt, bei print0 wird jedoch der Dateiname mit einem Nullzeichen am Ende der Zeile gedruckt, mit dem xarg mit -0 den vollständigen Pfad an xargs übergibt, ohne dass die Möglichkeit besteht, Leerzeichen zu erhalten Verwenden Sie einen zweiten oder dritten Parameter für den Befehl rm, was sehr schlecht sein kann!
X-Istence

7
@X: Neuere Findutils unterstützen eine -deleteAktion, die dies verkürzen könnte. @JT: Dies sucht rekursiv unter .. Kommt darauf an, wie viele Dateien und Unterverzeichnisse es gibt ... können Sie nicht einfach verbieten, dass diese hochgeladen werden?
Ephemient

1
Die Verwendung des -r(rekursiven) Flags wird in diesem Fall nicht empfohlen, da Sie keine Verzeichnisse löschen möchten.
Daniel Zohar

2
@IlmariKaronen: guter Punkt. Wäre es nicht command rmeine bessere (dh direktere) Lösung? (Mit "direkt" meine ich, dass es sich speziell um das vorliegende Problem und nichts anderes handelt und daher weniger wahrscheinlich unerwünschte Nebenwirkungen hat und auch für jeden, der den Code warten muss, selbsterklärender ist später.)
Bilderstürmer

93
find /var/www/html \( -name '.DS_Store' -or -name '._*' \) -delete

86

Neuere findutils unterstützt -delete, also:

find . -name ".DS_Store" -delete

Hinzufügen, -printum auch eine Liste der Löschungen zu erhalten.

Command funktioniert für Sie, wenn Sie ein aktuelles POSIX-System haben, glaube ich. Zumindest funktioniert es für mich unter OS X 10.8 und für andere, die es unter macOS 10.12 (Mojave) getestet haben.

Dank an @ephemient in einem Kommentar zu @ X-Istences Beitrag (dachte, es sei hilfreich genug, um eine eigene Antwort zu rechtfertigen).


1
Funktioniert auch in OSX 10.6.
Hoss

3
Sauberste und einfachste Lösung, +1!
Limist

6
@OneOfOne: Wie mein Kommentar sagt, habe ich dies von @ ephemient erhalten. Als Anfänger fand ich Ihre (vielleicht korrektere) Lösung weit weniger lesbar und verwendbar. Sie mögen funktional identisch sein, aber ich finde, dass diese Syntax mehr Klarheit bietet.
Rattray

1
Das '.' ist nicht erforderlich, da findstandardmäßig in das aktuelle Arbeitsverzeichnis zurückgegriffen wird.
Tom Russell

In neueren Versionen des Programms kann das Verzeichnis weggelassen werden und impliziert das aktuelle Arbeitsverzeichnis ( Wikipedia ). Sie benötigen noch .unter macOS 10.12 (Sierra).
Dem Pilafian

18

Einfacher Befehl:

rm `find ./ -name '.DS_Store'` -rf
rm `find ./ -name '._'` -rf

Viel Glück!


1
Das funktioniert super. ABER ein Wort der Vorsicht, ich habe gerade diesen rm -i Fund verwendet ./ -name '* py'` -rf , which did NOT prompt me to delete files. you will need to take it on the end (i.e. -rfi`). Gott sei Dank für mein Backup-Skript.
Ryanjdillon

1
Wenn es zu viele Dateien gibt, bricht dies mit dem Fehler:-bash: /bin/rm: Argument list too long
Viktor

12
cd /var/www/html && find . -name '.DS_Store' -print0 | xargs -0 rm
cd /var/www/html && find . -name '._*' -print0 | xargs -0 rm

2
Ich mochte dieses einfach besser, weil das "rm" kein "-r" hat, was für diese spezielle Aufgabe nicht notwendig ist.
Lotsoffreetime

6

Sie könnten zu zsh anstatt zu bash wechseln. Auf diese Weise können Sie ** verwenden, um Dateien an einer beliebigen Stelle in einem Verzeichnisbaum abzugleichen:

$ rm /var/www/html/**/_* /var/www/html/**/.DS_Store

Sie können sie auch folgendermaßen kombinieren:

$ rm /var/www/html/**/(_*|.DS_Store)

Zsh hat viele andere Funktionen, die Bash fehlen, aber für diese allein lohnt es sich, den Wechsel vorzunehmen. Es ist in den meisten (wahrscheinlich allen) Linux-Distributionen sowie in Cygwin und OS X verfügbar.

Weitere Informationen finden Sie auf der zsh-Website .


1
Ein mögliches Problem: Da Sie keine xargs verwenden, kann es zu Einschränkungen bei der Länge von Befehlszeilenargumenten kommen. Auch Bash 4 unterstützt **auch :-) (obwohl nicht standardmäßig, shopt -s globstarmuss eingestellt werden)
Ephemient

4
find . -name "FILE-TO-FIND"-exec rm -rf {} \;

Die Verwendung von exec für jede gefundene Datei ist nicht schnell. Es ist schneller, sie auszudrucken und dann mit xargs rm einmal aufzurufen.
X-Istence

3
Wenn Sie jedoch eine haben find, die dies unterstützt, +ist sie xargs-ähnlich: find . -name "FILE-TO-FIND" -exec rm -rf {} +- (außerdem fehlt Ihnen zuvor ein Leerzeichen -exec)
Bis auf weiteres angehalten.

3
Wir hatten zu meiner Zeit nie Xargs. Und wir mussten zur Schule gehen, bergauf in beide Richtungen .......
Martin Beckett

3

Beispiel zum rekursiven Löschen von "Thumbs.db";

find . -iname "Thumbs.db" -print0 | xargs -0 rm -rf

Validieren durch:

find . -iname "Thumbs.db"

Dies sollte nun keinen der Einträge mit "Thumbs.db" im aktuellen Pfad anzeigen.


Bitte stellen Sie sicher, dass Ihre Antwort eine Liste der gelöschten Inhalte druckt und erklären Sie, warum jemand sie verwenden möchte xargsund print0stattdessen exec(es gibt Gründe).
Josh Habdas

3

Es ist besser zu sehen, was entfernt wird, indem Sie dieser Antwort -print hinzufügen

find /var/www/html \( -name '.DS_Store' -or -name '._*' \) -delete -print

2

wenn Sie Bash 4.0 ++ haben

#!/bin/bash
shopt -s globstar
for file in /var/www/html/**/.DS_Store /var/www/html/**/._ 
do
 echo rm "$file"
done

2
Das Ausführen einer neuen Kopie von rm für jede Datei ist verschwenderisch.
X-Istence

2
@ X-Istence vorzeitige Optimierung ist verschwenderisch
Lucina

Upvoted für Originalität und Verwendung neuerer Bash-Innovationen.
Josh Habdas

1

Ein paar Dinge zu beachten:

'-delete' ist nicht rekursiv. Wenn also .TemporaryItems (Ordner) Dateien enthält, schlägt der Befehl fehl.

Es gibt viele dieser lästigen Dateien, die von Macs erstellt wurden: .DS_Store ._. DS_Store .TemporaryItems .apdisk

Dieser eine Befehl spricht alle an. Speichert beim wiederholten Ausführen von Find für mehrere Übereinstimmungen.

find /home/foo \( -name '.DS_Store' -or -name '._.DS_Store' -or -name '._*' -or -name '.TemporaryItems' -or -name '.apdisk' \) -exec rm -rf {} \;

0

Dies funktioniert auch:

sudo rm -rf 2018-03-*

hier Ihre Löschdateien mit Namen des Formats 2018-03- (etwas anderes)

halte es einfach


Sie erklären weder, wann jemand einem Befehl ein Präfix voranstellen möchte, sudonoch geben Sie Informationen darüber an, wie dies rmim Kontext Ihrer Antwort funktioniert.
Josh Habdas
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.