Eu passaria isso por um segundo grep
para removê-los:
grep -r --exclude={\*~,\*.map} "OK" bar/ | grep -vP '(?<!debug)\.js'
O -v
inverte o jogo, imprimindo linhas que não correspondem ao padrão e -P
permite Perl Compatible Regular Expressions que nos permitem usar visões traseiras negativos . Esse regex em particular corresponderá ao .js
que não é precedido por debug
quais meios (desde que estamos invertendo as correspondências) que somente esses .js
arquivos serão impressos.
No entanto, como o @QuestionOverflow apontou nos comentários, isso pode ter o efeito colateral não intencional de filtrar as linhas que contêm OK
e, js
uma vez que grep -v
é aplicada a toda a saída, não apenas ao nome do arquivo. Para evitar isso, basta adicionar dois pontos (que é o que é grep
usado para separar nomes de arquivos do conteúdo):
grep -r --exclude={*~,*.map} "OK" bar/ | grep -vP '(?<!debug).js:'
Isso ainda falhará se sua linha de entrada contiver foo.js:
ou se o nome do arquivo contiver :
. Portanto, para ter certeza, use uma abordagem diferente:
grep -Tr --exclude={*~,*.map} "OK" bar/ | grep -vP '(?<!debug).js\t'
As -T
causas grep
para imprimir uma guia entre o nome do arquivo e o conteúdo do arquivo. Portanto, se simplesmente adicionarmos um \t
no final da regex, ela corresponderá apenas aos nomes dos arquivos, e não ao conteúdo da linha.
Ainda assim, o usofind
pode fazer mais sentido, independentemente.
OK
e.js
na mesma linha?find
é provavelmente melhor para esse tipo de coisa. Conseguir o direitogrep
pode ser complicado, como você apontou :).failglob
opção definida no shell:bash: no match: --exclude=*~
Você precisa citar seus argumentos padrão glob para--exclude
escondê-los de expansão shell, por exemplo--exclude={\*~,\*.map}
Eu usaria
find
para localizar os arquivos e canalizar o resultado através dexargs
:Ele procura todos os arquivos que não correspondem "
*~
", "*.map
" ou "*.js
mas não*.debug.js
".Com
find
o uso, você pode procurar facilmente regras bastante complexas e essa abordagem evita que você acidentalmente remova falsos positivos, como poderia acontecer com o dobrogrep
.fonte
-exec grep OK {} +
vez dexargs
evitar um programa extra.-exec +
não-exec \;
, que executará o menor número possível de comandos, como os demaisxargs
.Com
zsh
você pode fazer:Desde que a lista de argumentos não seja muito longa, nesse caso, você sempre pode:
fonte
zsh
autoload zargs
zargs some/dir/**/^(*~|*.map|(^*debug).js) -- grep OK
Se você não se importa de ver a saída ligeiramente fora de ordem (se quiser, pode classificá-la):
Isso requer que o seu shell suporte
**
globbing recursivo: o zsh sai da caixa, o bash o faz depois da execuçãoshopt -s globstar
, o ksh93 o faz depois da execuçãoset -o globstar
.Sem
**
suporte no shell, você pode usar dois comandos grep:fonte
**
, mas parece haver algo errado com o argumento extra**/*.debug.js
, fazendo com que o grep interpreteOK
como um diretório. Você já tentou executá-lo?Você pode usar
ripgrep
. Por padrão, ele ignora arquivos ocultos e respeita seu.gitignore
arquivo.Você pode especificar as regras de inclusão ou exclusão usando os seguintes parâmetros:
Aqui estão alguns exemplos simples:
Aqui é a solução completa para excluir
*.~
,*.map
,*.js
, mas não*.debug.js
:Teste:
fonte