Linux, trouver tous les fichiers correspondant au modèle et supprimer

9

Vous cherchez à trouver tous les fichiers (récursivement) qui ont un trait de soulignement dans leur nom de fichier, puis supprimez-les via la ligne de commande.

Louis W
la source

Réponses:

16

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

slhck
la source
Au cours de toutes ces années, je n'ai jamais remarqué l'option -delete. Merci.
James Roth
2

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 {} \;
James Roth
la source
2
Juste un indice, si vous utilisez \+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.
Slhck
0

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
JdeBP
la source
-2

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)

Hayko Koryun
la source
1
Pour gérer les fichiers avec des espaces:, find . -type f -regex ".*_.*" -print0 | xargs -0 rm -fmais cela ne permet toujours pas de gérer les répertoires
James Roth