Supprimer les fichiers de manière récursive

140

Quelqu'un a-t-il une solution pour supprimer ces fichiers ._ et .DS_Store embêtants que l'on obtient après avoir déplacé des fichiers d'un Mac vers un serveur Linux?

spécifier un répertoire de démarrage et le laisser aller? comme / var / www / html / down ...

JT.
la source
Bien que ce ne soit pas un IMO en double, vous devriez jeter un coup d'œil à ceci: stackoverflow.com/questions/1280429/…
Grundlefleck
Bien que ce ne soit pas ce que vous demandez. Je dirais que c'est une meilleure solution: unix.stackexchange.com/questions/9665/…
Viktor

Réponses:

169

allez dans le répertoire et utilisez:

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

Non testé, essayez-les d'abord sans les xargs!

Vous pouvez remplacer le point après la recherche par le répertoire au lieu de passer d'abord au répertoire.

find /dir/here ...
X-Istence
la source
2
Je sais que sa question ne l'a pas demandé, mais je ne m'en souviens jamais: votre exemple gère-t-il les noms de fichiers avec des espaces?
Grundlefleck
4
Oui, c'est à cela que servent print0 et -0 à xargs. Normalement, il ne gérerait pas correctement les espaces, mais avec print0, il affichera le nom de fichier avec un caractère nul à la fin de la ligne, que xarg avec -0 utilisera ensuite pour passer le chemin complet à xargs sans aucune chance d'avoir l'espace blanc étant utilisé un deuxième ou troisième paramètre à la commande rm qui pourrait être vraiment mauvais!
X-Istence
7
@X: les nouveaux findutils prennent en charge une -deleteaction, ce qui pourrait raccourcir cela. @JT: Cela recherche récursivement sous .. Cela dépend du nombre de fichiers et de sous-répertoires qu'il y a ... ne pouvez-vous pas simplement interdire leur téléchargement?
éphémère
1
L'utilisation de l' -rindicateur (récursif) n'est pas recommandée dans ce cas car vous ne voulez supprimer aucun répertoire.
Daniel Zohar
2
@IlmariKaronen: bon point. Ne serait-il pas command rmune meilleure solution (c'est-à-dire plus directe)? (Par "direct", je veux dire qu'il traite spécifiquement du problème en question et rien d'autre, et est donc moins susceptible d'avoir des effets secondaires indésirables, et va également être plus explicite pour quiconque doit maintenir le code plus tard.)
iconoclaste
93
find /var/www/html \( -name '.DS_Store' -or -name '._*' \) -delete
OneOfOne
la source
86

Les nouveaux supports de findutils -delete, donc:

find . -name ".DS_Store" -delete

Ajouter -print pour également obtenir une liste des suppressions.

La commande fonctionnera pour vous si vous avez un système POSIX à jour, je crois. Au moins, cela fonctionne pour moi sur OS X 10.8 et pour d'autres qui l'ont testé sur macOS 10.12 (Mojave).

Merci à @ephemient dans un commentaire sur le message de @ X-Istence (a pensé que c'était assez utile pour justifier sa propre réponse).

hochet
la source
1
Fonctionne également sous OSX 10.6.
hoss
3
La solution la plus propre et la plus simple, +1!
limist
6
@OneOfOne: comme mon commentaire le dit, je l'ai obtenu de @ ephemient. En tant que débutant, j'ai trouvé votre solution (peut-être plus correcte) beaucoup moins lisible et utilisable. Ils peuvent être fonctionnellement identiques mais je trouve que cette syntaxe apporte plus de clarté.
rattray
1
Le '.' n'est pas nécessaire car findrécursive dans le répertoire de travail actuel par défaut.
Tom Russell
Dans les versions plus récentes du programme, le répertoire peut être omis, et cela impliquera le répertoire de travail actuel ( wikipedia ). Vous avez toujours besoin .de macOS 10.12 (Sierra).
Dem Pilafian
18

Commande simple:

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

Bonne chance!

KimKha
la source
1
Cela fonctionne très bien. MAIS un mot d'avertissement, je viens d'utiliser cette rm -i trouvaille ./ -name '* py'` -rf , which did NOT prompt me to delete files. you will need to take it on the end (i.e. -rfi`). Merci mon Dieu pour mon script de sauvegarde.
ryanjdillon
1
S'il y a trop de fichiers, cela rompt avec l'erreur:-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
mopoke
la source
2
J'ai mieux aimé celui-ci simplement parce que le "rm" n'a pas "-r" qui n'est pas nécessaire pour cette tâche spécifique.
lotsoffreetime
6

Vous pouvez passer à zsh au lieu de bash. Cela vous permet d'utiliser ** pour faire correspondre des fichiers n'importe où dans une arborescence de répertoires:

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

Vous pouvez également les combiner comme ceci:

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

Zsh a beaucoup d'autres fonctionnalités qui manquent à bash, mais celle-là seule vaut la peine d'être remplacée. Il est disponible dans la plupart (probablement toutes) les distributions Linux, ainsi que dans cygwin et OS X.

Vous pouvez trouver plus d'informations sur le site zsh .

Dave Kirby
la source
1
Un problème possible: puisque vous n'utilisez pas xargs, vous pourriez rencontrer la restriction de longueur d'argument de ligne de commande. De plus, Bash 4 prend **également en charge :-) (mais pas par défaut, shopt -s globstardoit être défini)
éphémère le
4
find . -name "FILE-TO-FIND"-exec rm -rf {} \;
Martin Beckett
la source
L'utilisation d'exec pour chaque fichier trouvé n'est pas rapide. Il est plus rapide d'avoir find les imprimer, puis d'utiliser xargs pour appeler rm une fois.
X-Istence
3
Cependant, si vous avez un findqui le prend en charge, il +ressemble à xargs: find . -name "FILE-TO-FIND" -exec rm -rf {} +- (il vous manque également un espace avant -exec)
pause jusqu'à nouvel ordre.
3
nous n'avons jamais eu de xargs de ma journée. Et nous avons dû marcher jusqu'à l'école, en montée dans les deux sens .......
Martin Beckett
3

Exemple pour supprimer "Thumbs.db" de manière récursive;

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

Validez par:

find . -iname "Thumbs.db"

Cela ne devrait maintenant afficher aucune des entrées avec "Thumbs.db", à l'intérieur du chemin actuel.

parasrish
la source
Veuillez vous assurer que votre réponse imprime une liste de ce qui est supprimé et expliquez pourquoi quelqu'un pourrait vouloir utiliser xargset à la print0place de exec(il y a des raisons).
Josh Habdas
3

Il est préférable de voir ce qui est supprimé en ajoutant -print à cette réponse

find /var/www/html \( -name '.DS_Store' -or -name '._*' \) -delete -print
Ahmad Yoosofan
la source
2

si vous avez Bash 4.0 ++

#!/bin/bash
shopt -s globstar
for file in /var/www/html/**/.DS_Store /var/www/html/**/._ 
do
 echo rm "$file"
done
ghostdog74
la source
2
Exécuter une nouvelle copie de rm pour chaque fichier est un gaspillage.
X-Istence
2
@ L'optimisation prématurée de X-Istence est un gaspillage
Lucina
Apprécié pour son originalité et l'utilisation d'innovations bash plus récentes.
Josh Habdas
1

Quelques points à noter:

«-delete» n'est pas récursif. Donc, si .TemporaryItems (dossier) contient des fichiers, la commande échoue.

Il y a beaucoup de ces fichiers embêtants créés par les macs: .DS_Store ._. DS_Store .TemporaryItems .apdisk

Cette seule commande s'adresse à tous. Enregistre de courir find encore et encore pour plusieurs matchs.

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

Cela fonctionne également:

sudo rm -rf 2018-03-*

ici vos fichiers de suppression avec des noms au format 2018-03- (autre chose)

rester simple

pranavhd
la source
Vous n'expliquez pas quand quelqu'un pourrait vouloir préfixer une commande avec sudoni vous ne fournissez aucune information sur son rmfonctionnement dans le contexte de votre réponse.
Josh Habdas