Supprimez les fichiers et les répertoires par leurs noms. Aucun fichier ou répertoire de ce nom

32

Je dois supprimer toutes les données compilées:

  • des répertoires appelés build,
  • des répertoires appelés obj,
  • fichiers * .so.

J'ai écrit une commande

find \( -name build -o -name obj -o -name *.so \) -exec rm -rf {} \;

cela parcourt tous les répertoires de manière récursive et supprime tout ce dont j'ai besoin.

Pourquoi ai-je une telle sortie à la fin? Peut-être que je devrais écrire une commande différente.

find: `./3/obj': No such file or directory
find: `./3/build': No such file or directory
find: `./1/obj': No such file or directory
find: `./1/build': No such file or directory
find: `./2/obj': No such file or directory
find: `./2/build': No such file or directory
Maksim Dmitriev
la source
sur quel système vous êtes? vous devriez toujours utiliser findcomme ceci en find /search_directory optionsomettant le répertoire de recherche n'est pas une bonne idée
Kiwy
La suppression automatique de ce type est une mauvaise idée. Vous pourriez demander à un script de vous donner des candidats, que vous devriez ensuite consulter pour vous assurer de ne supprimer aucun élément important ou nécessaire pour le système. Vous n'êtes pas explicite où vous exécutez ceci. Si vous ne faites cela que dans un espace utilisateur, je suppose que cela ne fait pas beaucoup de mal, mais vous devez vous assurer que vous ne le faites pas accidentellement. Vous voulez certainement exécuter un tel script en tant qu'utilisateur.
Faheem Mitha
@ Kiwy, @ FaheemMitha, la commande ne sera utilisée que dans le répertoire du projet; cela ne fera aucun mal là-bas.
Maksim Dmitriev
Connexes: stackoverflow.com/questions/22462124/…
Ciro Santilli a été ajouté

Réponses:

54

Utilisez -prunequand même sur les répertoires que vous allez supprimer pour findéviter de chercher plus facilement des fichiers:

find . \( -name build -o -name obj -o -name '*.so' \) -prune -exec rm -rf {} +

Notez également que cela *.sodoit être cité, sinon le shell peut l’étendre à la liste des .sofichiers du répertoire en cours.

L'équivalent de votre -regextype GNU 1 serait:

find . \( -name build -o -name obj -o -name '*?.so' \) -prune -exec rm -rf {} +

Notez que si vous utilisez une syntaxe spécifique à GNU, vous pouvez également utiliser à la -deleteplace de -exec rm -rf {} +. Avec -delete, GNU finds’allume -depthautomatiquement. Il n’exécute pas de commandes externes, il est donc plus efficace et plus sûr, car il supprime la situation critique dans laquelle une personne peut vous faire supprimer les mauvais fichiers en transformant un répertoire en un lien symbolique entre-temps. findtrouve un fichier et le rmsupprime (voir les info -f find -n 'Security Considerations for find'détails).

find . -regextype posix-egrep -regex '.*/((obj|build)(/.*)?|.+\.so)' -delete
Stéphane Chazelas
la source
-deletegère également des choses comme les espaces mieux
Izkata
@ Izkata, pas mieux que -exec rm -rf {} +ce qui n'a pas de problème avec ceux-là non plus.
Stéphane Chazelas
@StephaneChazelas - je suis confus {}- faut-il les citer ou non? Cela semble fonctionner sans guillemets, mais GNU Findutils Manual utilise cet '{}'exemple. Pourriez-vous s'il vous plaît clarifier?
grebneke
1
@grebneke, je pense qu'il y a quelque part un post qui prétend que des citations peuvent être nécessaires dans les très anciennes versions de csh, mais je n'ai jamais pu vérifier cette affirmation. Ils ne sont nécessaires dans aucune coque moderne que je connaisse. Ils ne sont certainement pas requis par POSIX. Les exemples POSIX ne les utilisent pas.
Stéphane Chazelas
3
Et -deletene peut pas être utilisé avec des répertoires.
St0rM
8

Je suppose que la raison en est que findl’arborescence de répertoires est d'abord effacée et que le contenu du répertoire est vérifié, ce qui n'est évidemment pas le meilleur ordre possible. Vous pouvez forcer findà vérifier le contenu en premier:

find . -depth ...

Vous devriez envisager d'utiliser -deletepour les fichiers et -exec rmdirpour les répertoires.

Hauke ​​Laging
la source
0

Ma solution

find . -regextype posix-egrep -regex ".*/(obj|build|.+\.so)" -prune -exec rm -rf {} +

+ vs \; dans la commande -exec

Maksim Dmitriev
la source
Cela ne fonctionnera pas toujours, seulement si aucune frontière entre les exécutions ne se produit dans un répertoire supprimé.
Gilles, arrête de faire le mal. »
@ Gilles, que veut dire "frontière entre exécutions"?
Maksim Dmitriev
1
-exec … {} +exécute la commande pour plusieurs fichiers à la fois, autant que possible sur la ligne de commande. S'il y a trop de fichiers (ou plus précisément si la longueur totale des chemins est trop longue), findexécutera plusieurs instances de rm, et pourrait donc finir par supprimer un répertoire qu'il traverse. C'est moins probable avec +que avec ;, mais +ne résout pas le problème.
Gilles 'SO- arrête d'être méchant'