Trouver des résultats dans grep pour l'exclusion de répertoire rapide

j'utilise avec succès find pour créer une liste de tous les fichiers du sous-répertoire courant, à l'exclusion de ceux du sous-répertoire "cache."Voici mon premier morceau de code:

find . -wholename './cach*' -prune -o -print

je souhaite maintenant insérer ceci dans une commande grep. Il semble que ce devrait être simple:

find . -wholename './cach*' -prune -o -print | xargs grep -r -R -i "samson"

... mais ceci renvoie des résultats qui sont principalement du répertoire cache. J'ai essayé de supprimer la référence xargs, mais ça fait ce à quoi vous vous attendez, exécuter le grep sur le texte du fichier les noms, plutôt que sur les fichiers eux-mêmes. Mon but est de trouver "samson" dans tous les fichiers qui ne sont pas du contenu caché.

je vais probablement contourner ce problème en utilisant simplement le double greps dans ce cas, mais je suis très curieux de savoir pourquoi cette doublure se comporte de cette façon. J'aimerais entendre des réflexions sur une façon de le modifier tout en utilisant ces deux commandes (car il y a des avantages de vitesse à le faire de cette façon).

<!-(C'est dans CentOS 5, btw.)

10
demandé sur eternalnewb 2012-07-19 20:41:15

3 réponses

wholename la correspondance peut être la raison pour laquelle elle inclut toujours les fichiers "cache". Si vous êtes à l'exécution de l' find commande dans le répertoire qui contient le dossier "cache", cela devrait fonctionner. Si non, essayez de le changer en -name '*cache*' à la place.

en outre, vous n'avez pas besoin de l' -r ou -R pour votre grep, qui lui dit de revenir à travers les répertoires - mais vous testez des fichiers individuels.

vous pouvez mettre à jour votre commande en utilisant la version une seule commande:

find . -name '*cache*' -prune -o -print0 | xargs -0 grep -il "samson"

ou

find . -name '*cache*' -prune -o -exec grep -iq "samson" {} \; -print

Remarque:-l dans la première commande indique grep "liste des fichiers" et non pas la ligne(s) qui correspondent. -q dans le deuxième fait la même chose; il dit grep pour répondre tranquillement, donc find va alors juste imprimer le nom du fichier.

9
répondu newfurniturey 2012-07-19 16:52:03

Vous avez dit grep lui-même de manière récursive (deux fois! -r et -R sont des synonymes). Puisque l'un des arguments que vous passez est . (le répertoire), grep recherche dans chaque fichier (certains deux fois, voire plus s'ils sont dans des sous-répertoires).

Si vous allez utiliser find et grep, faire ceci:

find . -path './cach*' -prune -o -print0 | xargs -0 grep -i "samson"

en utilisant -print0 et -0 fait fonctionner votre script même avec des noms de fichiers qui contiennent des espaces ou des signes de ponctuation caractère.

Toutefois, vous n'avez probablement pas besoin de s'embêter avec find ici, puisque GNU grep est capable d'exclure les répertoires:

grep -R --exclude-dir='cach*' -i "samson" .

(ceci exclut aussi ./deeply/nested/directory/cache. Si vous voulez seulement exclure les répertoires de cache au niveau supérieur, utilisez find comme vous l'avez fait.)

3
répondu Gilles 2012-07-19 17:01:13

-exec option sur find au lieu de les rediriger vers une autre commande. De là, vous pouvez utiliser grep "samson" {} \; pour chercher samson dans chaque fichier énuméré.

Par exemple:

find . -wholename './cach*' -prune -o -exec grep "samson" "{}" +
3
répondu Conner 2014-02-12 04:48:07