web-dev-qa-db-fra.com

Sous Linux, comment puis-je trouver tous les fichiers contenant une chaîne et les supprimer?

Je souhaite supprimer tous les fichiers contenant la chaîne foo. Comment puis-je faire cela en utilisant bash sous Linux?

16
Kitsos

Voici un moyen sûr:

grep -lrIZ foo . | xargs -0 rm -f --
  • -l imprime les noms de fichiers correspondant au modèle de recherche.
  • -r effectue une recherche récursive pour le modèle foo dans le répertoire donné .. Si cela ne fonctionne pas, essayez -R.
  • -I (capital i) provoque l'omission des fichiers binaires tels que les PDF.
  • -Z veille à ce que les noms de fichier se terminent par zéro (c'est-à-dire, nul-) de sorte qu'un nom contenant des espaces ne soit pas interprété de manière incorrecte (c'est-à-dire comme plusieurs noms au lieu d'un).
  • xargs -0 alimente les noms de fichiers de grep à rm -f, en séparant les mots par zéro (nul) octets (rappelez-vous de l'option -Z de grep).
  • -- est souvent oublié, mais il est très important de marquer la fin des options et de permettre la suppression des fichiers dont le nom commence par -.

Si vous souhaitez voir quels fichiers sont sur le point d'être supprimés, supprimez simplement la partie | xargs -0 rm -f -- et laissez l'option Z à grep.

Un autre utilisateur a suggéré quelque chose comme ce qui suit, qui ne doit pas être exécuté car cela pose un problème de sécurité:

files=`grep foo * | cut -d: -f1`
rm -f $files         # unsafe, do not run it!

Si j'ai des fichiers ImportantStuff que je ne veux pas supprimer et obsolete ImportantStuff contenant foo, alors je perds ImportantStuff (et pas obsolete ImportantStuff!) Lorsque j'exécute cette commande , parce que $files est séparé des espaces quand il est interprété. Il est dangereux de placer une liste de noms de fichiers dans une variable shell scalaire de cette manière.

32
Lekensteyn
$ find -type f -exec grep -q "foo" {} \; -exec echo rm -- {} \;

Ceci recherche récursivement les fichiers contenant foo. Le deuxième -exec n’est exécuté que si la première exec se termine correctement, c’est-à-dire si grep correspond. Lancez à sec et supprimez la echo si le résultat semble correct.

Ou bien

$ find -type f -exec grep -q "foo" {} \; -print

et

$ find -type f -exec grep -q "foo" {} \; -delete

comme suggéré par Lekensteyn.

17
Adrian Frühwirth

Je ferais ce que dit Adrian,

Mais j’ajouterais des limites de mot autour du foo afin de ne pas supprimer accidentellement les fichiers contenant "nourriture" (à moins que vous ne supprimiez tout ce qui contient de la nourriture.)

 $ find -type f -exec grep -q "\<foo\>" {} \; -delete

en fait, je redirigerais la sortie avant de supprimer pour pouvoir vérifier avant de supprimer:

 $ find -type f -exec grep -q "\<foo\>" > /tmp/list_of_files_to_delete
1
Petter H