web-dev-qa-db-fra.com

comment utiliser l'option grep --include pour plusieurs types de fichiers?

Quand je veux grep tous les fichiers html dans un répertoire, je fais ce qui suit

grep --include="*.html" pattern -R /some/path

qui fonctionne bien. Le problème est de savoir comment grep tous les fichiers html, htm, php de certains répertoires?

De cette Utilisez la syntaxe grep --exclude/- include pour ne pas grep via certains fichiers , il semble que je puisse faire ce qui suit

grep --include="*.{html,php,htm}" pattern -R /some/path

Mais malheureusement, cela ne fonctionnerait pas pour moi.
Pour info, ma version de grep est 2.5.1.

71
tianyapiaozi

Vous pouvez utiliser plusieurs drapeaux --include. Cela fonctionne pour moi:

grep -r --include=*.html --include=*.php --include=*.htm "pattern" /some/path/ 

Cependant, vous pouvez faire ce que Deruijter a suggéré. Cela fonctionne pour moi:

grep -r --include=*.{html,php,htm} "pattern" /some/path/

N'oubliez pas que vous pouvez utiliser find et xargs pour ce genre de choses pour:

find /some/path/ -name "*.htm*" -or -name "*.php" | xargs grep "pattern"

HTH

101
Steve

Utiliser {html,php,htm} ne peut fonctionner que comme une extension accolade, qui est une fonctionnalité non standard (non compatible POSIX) de bash, ksh et zsh.

  • En d'autres termes: n'essayez pas de l'utiliser dans un script qui cible /bin/sh - utilisez explicite plusieurs arguments --include dans ce cas.

  • grep lui-même ne pas comprend la notation {...}.

Pour qu'une extension d'accolade soit reconnue, il faut que soit un sans guillemet (partie d'un) jeton sur la ligne de commande.

Une extension d'accolade se développe en arguments multiples. Ainsi, dans le cas présent, grep finit par afficher les options multiples--include=..., comme si vous les aviez passées individuellement.

Les résultats d'une extension d'accolade sont soumis à globbing (extension de nom de fichier), qui a pitfalls:

  • Chaque argument résultant pourrait être étendu aux noms de fichiers correspondants s'il contenait des métacaractères sans guillemets tels que *.
    Bien que cela soit peu probable avec des jetons tels que --include=*.html (par exemple, vous devriez avoir un fichier littéralement nommé quelque chose comme --include=foo.html pour que quelque chose corresponde), cela vaut la peine de garder à l'esprit en général.

  • Si l'option de shell nullglob est activée (shopt -s nullglob) et que la sélection correspond à rien, l'argument sera rejeté.

Par conséquent, pour une solution entièrement robuste, utilisez les éléments suivants:

grep -R '--include=*.'{html,php,htm} pattern /some/path
  • '--include=*.' est traité comme un littéral, car il est entre guillemets simples; cela empêche l'interprétation par inadvertance de * en tant que caractère globulant.

  • {html,php,htm}, le - de nécessité - non cité extension d'accolade[1], se développe en 3 arguments, qui, en raison de {...}directement après le jeton '...', inclus ce jeton.

  • Par conséquent, après la suppression des guillemets par le shell, les arguments 3 _ {littéraux suivants sont finalement transmis à grep:

    • --include=*.html
    • --include=*.php
    • --include=*.htm

[1] Plus précisément, seules les parties pertinentes de la syntaxe de l'extension d'accolade ne doivent pas être citées, les éléments de la liste peuvent toujours être citées individuellement et doivent l'être si elles contiennent des métacaractères. cela pourrait entraîner des mouvements indésirables après l'expansion du corset; bien que cela ne soit pas nécessaire dans ce cas, ce qui précède pourrait être écrit comme suit:
'--include=*.'{'html','php','htm'}

17
mklement0

Essayez de supprimer les guillemets

grep --include=*.{html,php,htm} pattern -R /some/path
9
Deruijter

est-ce que ça ne marche pas? 

  grep pattern  /some/path/*.{html,php,htm} 
4
Vijay

Essayez ceci .- r fera une recherche récursive .- s supprimera les erreurs de fichier non trouvé .- n vous montrera le numéro de ligne du fichier où le motif est trouvé.

    grep "pattern" <path> -r -s -n --include=*.{c,cpp,C,h}
2
Pradeep

Utilisez grep avec la commande find

find /some/path -name '*.html' -o -name '*.htm' -o -name '*.php' -type f 
 -exec grep PATTERN {} \+

Vous pouvez également utiliser les options -regex et -regextype.

0

Cela fonctionne dans le même but, mais sans l'option --include. Cela fonctionne également sur grep 2.5.1.

grep -v -E ".*\.(html|htm|php)"
0
Kohei Mikami