Je souhaite supprimer tous les fichiers contenant la chaîne foo
. Comment puis-je faire cela en utilisant bash sous Linux?
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.
$ 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.
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