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.)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.
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.)
-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" "{}" +