Vous pouvez également utiliser globstar.
Construire des grep
commandes avec find
, comme dans la réponse de Zanna , est un moyen très robuste, polyvalent et portable de le faire (voir aussi la réponse de sudodus ). Et muru a publié une excellente approche de l'utilisation grep
de l' --include
option de . Mais si vous souhaitez utiliser uniquement la grep
commande et votre shell, il existe une autre façon de le faire - vous pouvez faire en sorte que le shell lui-même effectue la récursivité nécessaire :
shopt -s globstar # you can skip this if you already have globstar turned on
grep -H 'pattern' **/file.txt
L' -H
indicateur fait grep
afficher le nom du fichier même si un seul fichier correspondant est trouvé. Vous pouvez passer la -a
, -i
et des -n
drapeaux (de votre exemple) à grep
aussi bien, si c'est ce dont vous avez besoin. Mais ne passez pas -r
ou -R
lorsque vous utilisez cette méthode. C'est le shell qui récursive les répertoires en développant le modèle glob contenant **
, et nongrep
.
Ces instructions sont spécifiques au shell Bash. Bash est le shell utilisateur par défaut dans Ubuntu (et la plupart des autres systèmes d'exploitation GNU / Linux), donc si vous êtes sur Ubuntu et ne savez pas quel est votre shell, c'est presque certainement Bash. Bien que les shells populaires prennent généralement en charge les **
globs traversant les répertoires , ils ne fonctionnent pas toujours de la même manière. Pour plus d' informations, voir Stéphane Chazelas de excellente réponse à Le résultat de ls *, ls ** et *** ls sur Unix.SE .
Comment ça fonctionne
L' activation de l' option shell bash de globstar crée des **
chemins de correspondance contenant le séparateur de répertoire ( /
). C'est donc un glob récursif d'annuaire. Plus précisément, comme l' man bash
explique:
Lorsque l' option shell globstar est activée et que * est utilisé dans un contexte d'expansion de nom de chemin, deux * adjacents utilisés comme modèle unique correspondront à tous les fichiers et à zéro ou plusieurs répertoires et sous-répertoires. S'ils sont suivis d'un /, deux * adjacents ne correspondront qu'aux répertoires et sous-répertoires.
Vous devez être prudent avec cela, car vous pouvez exécuter des commandes qui modifient ou suppriment beaucoup plus de fichiers que vous n'en avez l'intention, surtout si vous écrivez **
quand vous vouliez écrire *
. (C'est sûr dans cette commande, qui ne change aucun fichier.) shopt -u globstar
Désactive l'option shell globstar.
Il existe quelques différences pratiques entre globstar et find
.
find
est beaucoup plus polyvalent que globstar. Tout ce que vous pouvez faire avec globstar, vous pouvez aussi le faire avec la find
commande. J'aime globstar, et parfois c'est plus pratique, mais globstar n'est pas une alternative générale à find
.
La méthode ci-dessus ne regarde pas à l'intérieur des répertoires dont les noms commencent par un .
. Parfois, vous ne voulez pas récupérer de tels dossiers, mais parfois vous le faites.
Comme avec un glob ordinaire, le shell construit une liste de tous les chemins correspondants et les transmet comme arguments à votre commande ( grep
) à la place du glob lui-même. Si vous avez tant de fichiers appelés file.txt
que la commande résultante serait trop longue pour que le système s'exécute, la méthode ci-dessus échouera. En pratique, vous auriez besoin (au moins) de milliers de ces fichiers, mais cela pourrait arriver.
Les méthodes qui utilisent find
ne sont pas soumises à cette restriction, car:
La façon dont Zanna construit et exécute une grep
commande avec potentiellement de nombreux arguments de chemin. Mais si plus de fichiers sont trouvés que ce qui peut être répertorié dans un seul chemin, l' action +
-terminated -exec
exécute la commande avec certains des chemins, puis l'exécute à nouveau avec quelques chemins supplémentaires, etc. Dans le cas d' grep
ing pour une chaîne dans plusieurs fichiers, cela produit le comportement correct.
Comme la méthode globstar couverte ici, cela imprime toutes les lignes correspondantes, avec des chemins ajoutés à chacune.
La voie de sudodus s'exécute grep
séparément pour chaque file.txt
trouvé. S'il y a beaucoup de fichiers, cela peut être plus lent que certaines autres méthodes, mais cela fonctionne.
Cette méthode recherche les fichiers et imprime leurs chemins, suivis des lignes correspondantes le cas échéant. Il s'agit d'un format de sortie différent du format produit par ma méthode, celle de Zanna et celle de muru .
Obtenir de la couleur avec find
L'un des avantages immédiats de l'utilisation de globstar est, par défaut sur Ubuntu, de grep
produire une sortie colorisée. Mais vous pouvez facilement obtenir cela find
aussi .
Les comptes utilisateurs dans Ubuntu sont créés avec un alias qui fait grep
vraiment tourner grep --color=auto
(courir alias grep
pour voir). C'est une bonne chose que les alias ne soient à peu près étendus que lorsque vous les émettez de manière interactive , mais cela signifie que si vous souhaitez find
invoquer grep
avec l' --color
indicateur, vous devrez l'écrire explicitement. Par exemple:
find . -name file.txt -exec grep --color=auto -H 'pattern' {} +