Jai beaucoup utilisé cela, lamélioration que jessaie dobtenir est déviter les noms de fichiers décho qui ne correspondent pas grep. Meilleure façon de procéder?
for file in `find . -name "*.py"`; do echo $file; grep something $file; done
Commentaires
- Connexes (sur Demandez à Ubuntu ): Rechercher récursivement un modèle / texte uniquement dans le nom de fichier spécifié dun répertoire?
Réponse
find . -name "*.py" -exec grep something {} \; -print
afficherait le nom du fichier après les lignes correspondantes.
find . -name "*.py" -exec grep something /dev/null {} +
afficherait le nom du fichier devant chaque ligne correspondante (nous ajoutons /dev/null
pour le cas où il ny aurait quun un le fichier correspondant comme grep
nimprime pas le nom du fichier sil na passé quun seul fichier à rechercher. Limplémentation GNU de grep
a une option -H
pour cela comme alternative).
find . -name "*.py" -exec grep -l something {} +
nimprimerait que les noms de fichiers des fichiers qui ont au moins une ligne correspondante.
Pour imprimer le nom de fichier avant les lignes correspondantes, vous pouvez utiliser awk à la place:
find . -name "*.py" -exec awk " FNR == 1 {filename_printed = 0} /something/ { if (!filename_printed) { print FILENAME filename_printed = 1 } print }" {} +
Ou appelez grep
deux fois pour chaque fichier – bien que « d soit moins efficace car il exécuterait au moins une commande grep
et jusquà deux pour chaque fichier (et lirait le contenu du fichier deux fois ):
find . -name "*.py" -exec grep -l something {} \; \ -exec grep something {} \;
Dans tous les cas, vous ne voulez pas faire une boucle sur la sortie de find
comme ça et noubliez pas de citer votre variables .
Si vous vouliez utiliser une boucle shell, avec les outils GNU:
find . -name "*.py" -exec grep -l --null something {} + | xargs -r0 sh -c " for file do printf "%s\n" "$file" grep something < "$file" done" sh
(fonctionne également sur FreeBSD et ses dérivés).
Answer
I Si vous utilisez GNU grep, vous pouvez utiliser son option -r
ou --recursive
pour effectuer cette recherche simple pour vous:
grep -r --include "*.py" -le "$regexp" ./ # for filenames only grep -r --include "*.py" -He "$regexp" ./ # for filenames on each match
Vous navez besoin que de find
si vous en avez besoin prédicats plus avancés.
Commentaires
- Selon la version de GNU
grep
,grep
peut ou non regarder à lintérieur des liens symboliques ou traverser des liens symboliques vers des répertoires. Vous pouvez également trouver des variantes dans la gestion dautres types de fichiers non réguliers.
Réponse
Vous peut dire à grep dinclure le nom de fichier dans la sortie. Donc, sil y a une correspondance, elle sera affichée sur la console; sil ny a pas de correspondance dans un fichier, aucune ligne ne sera imprimée pour ce fichier.
find . -name "*.py" | xargs grep -n -H something
À partir de man grep
:
-H Always print filename headers with output lines -n, --line-number Each output line is preceded by its relative line number in the file, starting at line 1. The line number counter is reset for each file processed. This option is ignored if -c, -L, -l, or -q is specified.
Si vos fichiers peuvent avoir des noms avec des espaces, vous devez changer le tube pour utiliser les caractères NUL comme séparateur. La commande complète ressemblera maintenant à ceci:
find . -name "*.py" -print0 | xargs -0 grep -n -H something
Answer
Vous pouvez essayez quelque chose comme:
find . -name "*.py:" -exec grep -l {} \;
Cette commande exec grep pour chaque fichier, découverte par la commande find et sa fonction de commande find standard
Réponse
Utilisez largument -l
.
for file in `find . -name "*.py"`; do grep -l something $file && grep something $file; done
Une autre utilisation de recherche serait:
for file in $(find . -name "*.py" -exec grep -l something "{}" +); do echo "$file"; grep something $file; done
Answer
Là sont des grep
alternatives qui, par défaut, affichent leurs résultats dans le format souhaité. Les 2 plus populaires que je connais sont ag
(a.k.a. « the silver searcher ») et ack
. ag
est présenté comme une alternative plus rapide à ack
.
$ ag "^\w+\s*\w+\(" ~/build/i3/src build/i3/src/display_version.c 58:void display_running_version(void) { build/i3/src/load_layout.c 42:static TAILQ_HEAD(focus_mappings_head, focus_mapping) focus_mappings = 518:json_content_t json_determine_content(const char *filename) { 575:void tree_append_json(Con *con, const char *filename, char **errormsg) { build/i3/src/x.c 64:CIRCLEQ_HEAD(state_head, con_state) state_head = 67:CIRCLEQ_HEAD(old_state_head, con_state) old_state_head = 70:TAILQ_HEAD(initial_mapping_head, con_state) initial_mapping_head = 97:void x_con_init(Con *con, uint16_t depth) { ...
Je ne peux pas vous montrer ici, mais la sortie est parfaitement colorée. Jobtiens les noms de fichiers en vert olive, les numéros de ligne en jaune or et la pièce correspondante dans chaque ligne en rouge sang. Les couleurs sont cependant personnalisables.