Quando quero executar grep em todos os arquivos html em algum diretório, faço o seguinte
grep --include="*.html" pattern -R /some/path
que funciona bem. O problema é como fazer o grep de todos os arquivos html, htm, php em algum diretório?
Deste Use grep --exclude / - incluem sintaxe para não grep através de determinados arquivos , parece que eu posso fazer o seguinte
grep --include="*.{html,php,htm}" pattern -R /some/path
Mas, infelizmente, não funcionaria para mim.
FYI, minha versão grep é 2.5.1.
xargs
. Isso também vale uma leitura rápida. HTH.*
ainda está sujeito a globbing como parte do token no qual está embutido , apenas acontece de não corresponder a nada neste caso, porque apenas arquivos com o nome literal de algo como--include=foo.html
corresponderiam. Para ser seguro, cite o*
(o que você pode fazer individualmente\*
). Como um bônus adicional, isso torna visualmente mais claro que não é o shell que deve realizar o globbing neste caso.find
solução: usar em-exec grep "pattern" {} +
vez de| xargs grep "pattern"
é mais robusto (trata nomes de arquivos com espaços, por exemplo) e também mais eficiente.Usando
{html,php,htm}
só pode funcionar como uma expansão cinta , o que é uma característica fora do padrão (não compatíveis com POSIX) debash
,ksh
ezsh
.Em outras palavras: não tente usá-lo em um script direcionado
/bin/sh
- use vários argumentos explícitos--include
nesse caso.grep
em si não entende{...}
notação.Para que uma expansão de chave seja reconhecida, ela deve ser um token sem aspas (parte de um) na linha de comando.
Uma expansão de chave se expande para vários argumentos , portanto, no caso em questão,
grep
acaba vendo várias--include=...
opções, como se você as tivesse passado individualmente.Os resultados de uma expansão de chave estão sujeitos a globbing (expansão de nome de arquivo) , que tem armadilhas :
Cada argumento resultante pode ser expandido para nomes de arquivo correspondentes se ele contiver metacaracteres globbing não citados, como
*
.Embora isso seja improvável com tokens como
--include=*.html
(por exemplo, você teria que ter um arquivo com o nome literal de algo semelhante--include=foo.html
para que algo correspondesse), é importante ter em mente em geral.Se a
nullglob
opção shell for ativada (shopt -s nullglob
) e globbing não corresponder a nada , o argumento será descartado .Portanto, para uma solução totalmente robusta , use o seguinte:
'--include=*.'
é tratado como literal , por estar entre aspas simples ; isso evita a interpretação inadvertida de*
um caractere globbing.{html,php,htm}
, a - necessariamente - expansão de chaves sem aspas [1] , expande-se para 3 argumentos, que, devido a{...}
seguir diretamente o'...'
token , incluem esse token.Portanto, após a remoção da citação pelo shell, os três argumentos literais a seguir são finalmente transmitidos para
grep
:--include=*.html
--include=*.php
--include=*.htm
[1] Mais precisamente, são apenas as partes relevantes à sintaxe da expansão da chave que devem ser não citadas, os elementos da lista ainda podem ser citados individualmente e devem ser se contiverem metacaracteres globbing que podem resultar em globbing indesejado após a expansão da chave; embora não seja necessário neste caso, o acima pode ser escrito como
'--include=*.'{'html','php','htm'}
fonte
bash
em qualquer plataforma quebash
rode.Tente remover as aspas duplas
fonte
grep --include=\*.{html,php,htm} pattern -R /some/path
. Funcionou para mimnão está funcionando?
fonte
Experimente isso. -r fará uma pesquisa recursiva. -s irá suprimir erros de arquivo não encontrado. -n mostrará o número da linha do arquivo onde o padrão foi encontrado.
fonte
-I
ao conjunto padrão. Ele pula arquivos binários (que quase nunca são pesquisados), portanto, aumenta a eficiência. Então vamos lágrep -rIns ...
que toca acústico bem :)Funciona com o mesmo propósito, mas sem
--include
opção. Ele também funciona no grep 2.5.1.fonte
Use
grep
comfind
comandoVocê pode usar as opções
-regex
e-regextype
também.fonte