Comment puis-je trouver tous les fichiers qui ne contiennent pas une chaîne de texte?

40

Quelle commande concise puis-je utiliser pour rechercher tous les fichiers ne contenant PAS de chaîne de texte?

J'ai essayé ceci (en utilisant -v pour inverser les paramètres de grep) sans succès:

find . -exec grep -v -l shared.php {} \;

Quelqu'un a dit que cela fonctionnerait:

find . ! -exec grep -l shared.php {} \;

Mais cela ne semble pas fonctionner pour moi.

Cette page a cet exemple:

find ./logs -size +1c  > t._tmp
while read filename
do
     grep -q "Process Complete" $filename
     if [ $? -ne 0 ] ; then
             echo $filename
     fi
done < t._tmp
rm -f t_tmp

Mais c'est lourd et pas du tout concis.

ps: Je sais que cela grep -L *suffira, mais je veux vraiment savoir comment utiliser la commande find en combinaison avec grep pour exclure des fichiers.

pss: De plus, je ne suis pas sûr de savoir comment grep inclut des sous-répertoires avec la grep -L *syntaxe, mais je veux tout de même savoir comment l'utiliser avec find:)

cwd
la source
1
La première commande que vous avez écrite a bien fonctionné sur mon ordinateur. Quelle version de find utilisez-vous? Et puisque nous y sommes, spécifiez peut-être le système d'exploitation que vous utilisez ..
rahmu
@rahmu, cette commande ne fonctionne presque toujours pas comme prévu. Vous avez probablement eu un cas très spécifique. Veuillez consulter unix.stackexchange.com/questions/339619/…
sgnsajgon

Réponses:

8
find . -type f | xargs grep -H -c 'shared.php' | grep 0$ | cut -d':' -f1    

OU

find . -type f -exec grep -H -c 'shared.php' {} \; | grep 0$ | cut -d':' -f1

Ici, nous calculons le nombre de lignes correspondantes (en utilisant -c) dans un fichier si le compte est 0, puis le fichier requis, nous avons donc coupé la première colonne, c’est-à-dire le nom du fichier, de la sortie.

Sachin Divekar
la source
6
C'est terriblement compliqué. Voir la réponse de Kevin .
Gilles 'SO- arrête d'être méchant'
@ Gilles oui je suis d'accord avec toi. J'ai +1 sa réponse.
Sachin Divekar
6
Ce n'est pas seulement "terriblement compliqué" mais aussi faux car cela listerait tous les fichiers contenant un multiple de 10 lignes correspondant au motif. Même si cela grepa été fixé cela supposerait toujours pas les noms de fichiers contenant :ou newline caractères ...
don_crissti
@don_crissti, merci de le mentionner! Néanmoins, à moins que vous utilisiez beaucoup de code copier-coller, la solution ci-dessus est un gimmick bien sympathique.
Ufos
@ Ufos - Je ne comprends vraiment pas votre commentaire ... C'est faux . Quoi qu'il en soit, n'hésitez pas à l'utiliser si cela ressemble à un "truc vraiment sympa" pour vous ...
don_crissti
58

Votre recherche devrait fonctionner si vous modifiez -v -l(fichiers -Lne contenant aucune ligne ne correspondant) en (fichiers sans lignes correspondant), mais vous pouvez également utiliser grepl' -roption récursive ( ):

grep -rL shared.php .
Kevin
la source
quelle trouvaille devrait fonctionner?
cwd
@ Kevin - désolé, find . -exec grep -v -l shared.php {} \;(et toutes les autres variantes que j'ai essayées) ne fonctionne pas pour moi. Je suis sous OS X mais je ne pense pas que cela devrait compter. Je vous ai donné un +1 parce que j'avais oublié l' -roption.
cwd
@cwd Je sais que c'est vieux, mais je veux laisser cela aux futurs lecteurs: le fait que vous soyez sur OS X fait une différence. Mac OSX utilise les commandes FreeBSD. La plupart des gens ici assument des commandes de style Linux (GNU). Ils ont différents arguments, différentes manières de gérer les détails.
Rich Homolka
À compter de 2016, OSX semble prendre en charge-L
David Moles
@ Kevin J'ai dit que oui, pas que ce ne soit pas le cas. :) pas que quiconque ait dit explicitement que non, mais les commentaires étaient déroutants (et j'ai certainement rencontré d'autres problèmes OS X / BSD vs GNU).
David Moles
4

Je sais que cela grep -L *suffira, mais je veux vraiment savoir comment utiliser la findcommande en combinaison avec greppour exclure des fichiers.

Vous pouvez utiliser findet grepcomme ceci:

find . -type f ! -exec grep -q 'PATTERN' {} \; -print

Ici, -printn'est exécuté que si l'expression précédente: ! -exec ... {}évalue comme true.
Donc, pour chaque fichier trouvé, grep -q 'PATTERN'est executé, si le résultat est falsealors l'expression entière est ! -exec grep -q 'PATTERN'évaluée comme trueet le nom du fichier est printédité.

don_crissti
la source
2
Celui-ci a l'avantage d'être standard et portable.
Stéphane Chazelas
Il y a une différence avec GNU, grep -Len ce sens qu'il inclura également les fichiers non lisibles dans la liste.
Stéphane Chazelas
1

Vous trouvez que le résultat ne correspond pas à l'option -L

grep -iL shared.php .
prakash
la source