grep, mais seulement certaines extensions de fichier

966

Je travaille sur l'écriture de certains scripts dans grepcertains répertoires, mais ces répertoires contiennent toutes sortes de types de fichiers.

Je veux grepjuste .het .cpppour l'instant, mais peut-être quelques autres à l'avenir.

Jusqu'à présent, j'ai:

{ grep -r -i CP_Image ~/path1/;

grep -r -i CP_Image ~/path2/;

grep -r -i CP_Image ~/path3/;

grep -r -i CP_Image ~/path4/;

grep -r -i CP_Image ~/path5/;} 

| mailx -s GREP [email protected]

Quelqu'un peut-il me montrer comment j'ajouterais maintenant uniquement les extensions de fichier spécifiques?

Jason
la source
13
Essayé grep -r -i CP_Image ~/path1/*.{h,cpp}?
8
Utilisez The Silver Searcher : ag -i CP_Image ~/path[1-5] | mailx -s GREP [email protected]. Travail accompli.
Johnsyweb
Utilisez egrep (est probablement pré-installé sur votre système), puis vous pouvez utiliser une expression régulière.
Dogweather
8
Les gars de GNU ont vraiment gâché quand ils ont ajouté -rà la greprecherche de fichiers car cela rompt le mantra UNIX d'avoir des outils qui "font une chose et le font bien". Il existe un excellent outil pour rechercher des fichiers avec un nom TRÈS évident.
Ed Morton

Réponses:

1354

Utilisez simplement le --includeparamètre, comme ceci:

grep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345] | mailx -s GREP [email protected]

cela devrait faire ce que vous voulez.

Pour prendre l'explication de la réponse de HoldOffHunger ci-dessous:

  • grep: commande

  • -r: récursivement

  • -i: ignore-case

  • --include \*.cpp: tous * .cpp: fichiers C ++ (échappez avec \ juste au cas où vous auriez un répertoire avec des astérisques dans les noms de fichiers)

  • ./: Commence au répertoire actuel.

Nelson
la source
123
Pour mémoire: -r (récursif) -i (ignore-case) --include (recherche uniquement les fichiers qui correspondent au modèle de fichier)
Luis
34
Peut être encore optimisé pourgrep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345]
zwol
1
@Hong où est la documentation que -R est pour les liens symboliques?
titus
8
Cet exemple semble avoir un score élevé car il couvre un large éventail de possibilités, mais la réponse donnée ci-dessous de grep -r --include = *. Txt 'searchterm' ./ explique vraiment l'essence de la réponse
David Casper
10
pourquoi ne pas utiliser des guillemets doubles au lieu d'une barre oblique inverse? par exemple:grep -r -i --include="*.h" --include="*.cpp" CP_Image
pambda
283

Certaines de ces réponses semblaient trop lourdes en syntaxe, ou elles ont généré des problèmes sur mon serveur Debian. Cela a parfaitement fonctionné pour moi:

Révolution PHP: Comment grep des fichiers sous Linux, mais seulement certaines extensions de fichiers?

À savoir:

grep -r --include=\*.txt 'searchterm' ./

... ou version insensible à la casse ...

grep -r -i --include=\*.txt 'searchterm' ./
  • grep: commande

  • -r: récursivement

  • -i: ignore-case

  • --include: all * .txt: fichiers texte (échapper avec \ juste au cas où vous auriez un répertoire avec des astérisques dans les noms de fichiers)

  • 'searchterm': Que rechercher

  • ./: Commence au répertoire actuel.

HoldOffHunger
la source
7
Vous devez échapper à l' *utilisation de \*.cppou '*.cpp'. Sinon, il ne donnera pas le résultat attendu lorsque le répertoire de travail contient des *.txtfichiers.
Melebius
@Melebius pouvez-vous expliquer pourquoi il doit s'échapper - cela a-t-il quelque chose à voir avec les extensions CPP ou TXT que vous avez mentionnées? Ou avez-vous simplement utilisé ces exemples?
Simon East
2
@SimonEast Ces extensions sont celles utilisées dans cette question et réponse, rien de spécial sinon. Cela fonctionnerait probablement sans s'échapper lors de l'utilisation, --include=<pattern>mais il est important de s'échapper *avec --include <pattern>(un espace au lieu de =) qui semble très similaire autrement.
Melebius
52
grep -rnw "some thing to grep" --include=*.{module,inc,php,js,css,html,htm} ./
Yuri Malov
la source
3
grep -rn "quelque chose à grep" --include = *. {module, inc, c, h} *
ashish
3
Bonne réponse. Plus propre que l'accepté sur IMO mais vous devez ajouter des critères de recherche comme l'a noté
@ashish
pourquoi l' --includeoption après l'aiguille, pas avec d'autres options?
vladkras
@vladkras, que voulez-vous dire par aiguille? C'est ça --?
heretoinfinity
50

Que diriez-vous:

find . -name '*.h' -o -name '*.cpp' -exec grep "CP_Image" {} \; -print
Amir Afghani
la source
5
je suggère de regrouper ces -namearguments. des choses étranges peuvent arriver si vous ne le faites pas. find . \( -name '*.h' -o -name '*.cpp' \) -exec grep "CP_Image" {} \; -print
nullrevolution
utiliser avec "-type f" supplémentaire pour ignorer tous les objets de répertoire, uniquement intéressés par les fichiers.
kensai
1
J'ai utilisé cette méthode pendant des années et cela fonctionne, mais c'est beaucoup plus lent que grep récursif, car l'exec de find génère un processus grep distinct pour chaque fichier à rechercher.
beaudet le
L'adressage du commentaire de @ beaudet findpeut éventuellement regrouper les arguments, réduisant au minimum les invocations du processus appelé. find . \( -name \*.h -o -name \*.cpp \) -exec grep -H CP_Image {} + Ceci est suggéré mais non mis en évidence dans la réponse de @ fedorqui ci-dessous et constitue une amélioration intéressante. L' -Hargument de grep ici est utile lorsque find identifie uniquement un seul fichier correspondant. Cela pourrait éliminer l'utilisation de -printdans la réponse. Si votre liste totale de fichiers est suffisamment petite, l'utilisation d'un glob de shell récursif (par exemple. {path1,path2}/**/*.{cpp,h}) Peut être préférable.
Malcolm
19

Il n'y a pas d'option -r sur les serveurs HP et Sun, cela a fonctionné pour moi sur mon serveur HP

find . -name "*.c" | xargs grep -i "my great text"

-i est pour la recherche de chaîne insensible à la casse

Sam B
la source
1
Je suis tombé sur plusieurs serveurs pour des sociétés d'hébergement Web qui n'ont pas l'option --include disponible pour fgrep et c'est la ligne de commande que j'utilise dans ces cas.
Borgboy
L'option --include n'est également pas disponible lors de l'utilisation de Git pour Windows (MinGW / MSys).
Darren Lewis
@DarrenLew est disponible dans Git Bash pour Windows. Mais étrangement, il ajoute des alias colorés comme llmais n'ajoute pas --color=autoà grep.
Xeverous
Cela devrait être la réponse acceptée pour l'exhaustivité, la portabilité et la brièveté!
Grant Foster
12

Comme il s'agit de trouver des fichiers, utilisons-le find!

GNU vous trouver en utilisant pouvez utiliser l' -regexoption pour trouver ces fichiers dans l'arborescence des répertoires dont l' extension est soit .hou .cpp:

find -type f -regex ".*\.\(h\|cpp\)"
#            ^^^^^^^^^^^^^^^^^^^^^^^

Ensuite, il s'agit juste d'exécuter grepsur chacun de ses résultats:

find -type f -regex ".*\.\(h\|cpp\)" -exec grep "your pattern" {} +

Si vous n'avez pas cette distribution de find, vous devez utiliser une approche comme Amir Afghani , en utilisant -opour concaténer les options ( le nom se termine par .hou avec.cpp ):

find -type f \( -name '*.h' -o -name '*.cpp' \) -exec grep "your pattern" {} +
#            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Et si vous voulez vraiment l'utiliser grep, suivez la syntaxe indiquée pour --include:

grep "your pattern" -r --include=*.{cpp,h}
#                      ^^^^^^^^^^^^^^^^^^^
fedorqui 'SO arrête de nuire'
la source
7

Le moyen le plus simple est

find . -type  f -name '*.extension' | xargs grep -i string 
user3640130
la source
3

ag (le chercheur d'argent) a une syntaxe assez simple pour cela

       -G --file-search-regex PATTERN
          Only search files whose names match PATTERN.

donc

ag -G *.h -G *.cpp CP_Image <path>
Eldamir
la source
en utilisant ag 2.2.0, je devais mettre mes drapeaux en dernier:ag _string_to_find_ -G _filename_regex_
ryanrain
3

La réponse ci-dessous est bonne:

grep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345] | mailx -s GREP [email protected]

Mais peut être mis à jour pour:

grep -r -i --include \*.{h,cpp} CP_Image ~/path[12345] | mailx -s GREP [email protected]

Ce qui peut être plus simple.

hao
la source
1

Doit écrire "-exec grep" pour chaque "-o -name"

find . -name '*.h' -exec grep -Hn "CP_Image" {} \; -o -name '*.cpp' -exec grep -Hn "CP_Image" {} \;

Ou regroupez-les par ()

find . \( -name '*.h' -o -name '*.cpp' \) -exec grep -Hn "CP_Image" {} \;

l'option '-Hn' affiche le nom et la ligne du fichier.

où23
la source
1

Je suis au courant de cette question est un peu daté, mais je voudrais partager la méthode que je l' utilise normalement pour trouver .c et .h fichiers:

tree -if | grep \\.[ch]\\b | xargs -n 1 grep -H "#include"

ou si vous avez également besoin du numéro de ligne:

tree -if | grep \\.[ch]\\b | xargs -n 1 grep -nH "#include"
À M
la source