Réponses:
C'est la variante la plus sûre et la plus rapide:
find /path -type f -name '*_*' -delete
Il ne nécessite pas de tuyauterie et ne casse pas si les fichiers contiennent des espaces, des caractères globaux ou tout autre élément susceptible d’être étouffé par d’autres constructions. La règle la plus simple à retenir ici est de ne jamais analyser la findsortie . Et jamais grepsur les noms de fichiers si vous voulez faire quelque chose avec eux plus tard. Vous pouvez faire presque n'importe quoi avec finddirectement.
Voir aussi: Manuel GNU find- Supprimer des fichiers
Cela inclut les répertoires considérés comme des fichiers. Certains des autres exemples utilisant xargs échoueront si le nom du fichier contient des espaces.
find . -name '*_*' -exec rm -rf {} \;
Si vous ne voulez que des fichiers réguliers:
find . -type f -name '*_*' -exec rm -f {} \;
\+au lieu de \;votre commande sera plus rapide car il substituera le nom de tous les fichiers trouvés au lieu d'appeler rmun à la fois.
Bon, faisons cela progressivement.
Comme première étape, il s’agit simplement d’un exercice simple consistant à transmettre un caractère générique à la findcommande, en se rappelant de le citer bien sûr et en exécutant la rmcommande pour chaque fichier trouvé:
find ${BASE_DIR}/ -name '*_*' -exec rm {} \;
Mais bien sûr, c'est terriblement inefficace. Il lance tout un rmprocessus pour chaque fichier individuel. Donc, bien que nous puissions faire un petit détour, \+ce n’est pas ce que nous allons finir, prenons donc le chemin le plus court et introduisons xargspour regrouper les noms de fichiers en groupes:
find ${BASE_DIR}/ -name '*_*' -print | xargs rm
Mais cela a deux failles de sécurité. Premièrement, si un nom de fichier trouvé commence par un signe moins, rmil le traitera comme une option de ligne de commande plutôt que comme un nom de fichier et générera une erreur. (La -exec rm {}version a également ce problème.) Deuxièmement, les noms de fichiers contenant des espaces ne seront pas gérés correctement par xargs. Donc, une autre itération est de rendre cela un peu plus à l'épreuve des balles:
find ${BASE_DIR}/ -name '*_*' -print0 | xargs -0 rm --
Et, bien sûr, il y a les fonctionnalités interactives de ce rmque vous ne voulez probablement pas:
find ${BASE_DIR}/ -name '*_*' -print0 | xargs -0 rm -f --
Les options -print0et -0ne sont pas standards, mais GNU findet xargs, ainsi que FreeBSD findet xargs, les comprennent. Cependant, même cela peut être amélioré. Nous n'avons pas besoin de générer de processus supplémentaires. GNU et FreeBSD findpeuvent appeler l’ unlink(2)appel système directement:
find ${BASE_DIR}/ -name '*_*' -delete
En guise de dernière mesure préventive pour vous empêcher de faire plus que ce que vous aviez prévu dans certaines circonstances, rappelez-vous que le système de fichiers peut contenir plus que des fichiers normaux:
find ${BASE_DIR}/ -name '*_*' -type f -delete
find . -type f -regex ".*_.*" | xargs rm -f
l'explication
-type f trouve que seuls les fichiers
-regex ".*_.*"sélectionne uniquement les fichiers
xargs rm -fcontenant un trait de soulignement, puis supprime le fichier sélectionné de manière forcée (ne demande jamais avant de supprimer)
find . -type f -regex ".*_.*" -print0 | xargs -0 rm -fmais cela ne permet toujours pas de gérer les répertoires