Quero excluir o arquivo ./test/main.cpp
da minha pesquisa.
Aqui está o que estou vendo:
$ grep -r pattern --exclude=./test/main.cpp
./test/main.cpp:pattern
./lib/main.cpp:pattern
./src/main.cpp:pattern
Eu sei que é possível obter a saída que eu quero usando vários comandos em um arranjo de tubos e filtros, mas há algumas citações / escape que farão grep
entender o que eu quero nativamente?
command-line
grep
nobar
fonte
fonte
--exclude-dir
). É por isso que eu gostaria que o grep execute a exclusão de forma nativa.Respostas:
grep
Não é possível fazer isso para o arquivo em um determinado diretório, se você tiver mais arquivos com o mesmo nome em diretórios diferentes, use find:find . -type f \! -path './test/main.cpp' -exec grep pattern {} \+
fonte
\!
e\+
? Parece funcionar bem sem as barras invertidas.grep
não pode fazer isso, use emfind
vez disso" - perfeito.Eu não acho que é possível com o GNU
grep
. Você não precisa de canos embora.Com
find
:Com
zsh
:(exclui arquivos ocultos, também para excluir .git, .svn ...).
fonte
Eu poderia escrever um livro: "A arte perdida de
xargs
". Ofind ... -exec … ';
lança um grep para cada arquivo (mas a variante com-exec … +
não). Bem, estamos perdendo ciclos de CPU hoje em dia. Por que não, certo? Mas se desempenho, memória e poder são um problema: use xargs:Do GNU
find
's-print0
vaiNUL
-terminate sua saída exargs
'-0
honras de opção que formato como entrada. Isso garante que quaisquer caracteres engraçados que seu arquivo tenha, o pipeline não ficará confuso. A-r
opção garante que não haja erro, casofind
não encontre nada.Observe que agora você pode fazer coisas como:
O GNU grep's
-z
faz o mesmo que o xargs '-0
.fonte
find -exec (cmd) {} +
funciona da mesma formaxargs
efind -exec (cmd) {} \;
funciona da mesma forma quexargs -n1
. Em outras palavras, sua declaração só está correta se a\;
versão for usada.xargs
é menos eficiente do que a utilização-exec … +
(embora marginalmente). Nenhuma das respostas aqui sequer menciona-exec … \;
.-exec ... +
adicionado em janeiro de 2005. Sim, não estou desatualizado ... de jeito nenhum.Se seus
find
suportes-path
foram adicionados ao POSIX em 2008, mas ainda estão ausentes no Solaris:fonte
-path
não é POSIX?Para o registro, aqui está a abordagem que eu prefiro:
Mantendo o
grep
comando no início do comando, acho que isso é um pouco mais claro - além de não desabilitargrep
o realce de cores. Em certo sentido, usarfind
uma substituição de comando é apenas uma maneira de estender / substituir o subconjunto (limitado) de pesquisa de arquivos dagrep
funcionalidade de.Para mim, a
find -exec
sintaxe é meio misteriosa. Uma complexidadefind -exec
é a (às vezes) necessidade de escapar vários caracteres (principalmente se\;
for usado no Bash). Apenas para fins de colocar as coisas em contextos familiares, os dois comandos a seguir são basicamente equivalentes:Se você deseja excluir subdiretórios , pode ser necessário usar um curinga. Eu não entendo completamente o esquema aqui - fale sobre arcano :
Uma observação adicional para generalizar
find
soluções baseadas em uso em scripts : Agrep
linha de comando deve incluir a opção-H
/--with-filename
. Caso contrário, ele alterará a formatação da saída sob a circunstância de que exista apenas um nome de arquivo nos resultados da pesquisafind
. Isso é notável porque não parece ser necessário se você estiver usandogrep
a pesquisa de arquivos nativa (com a-r
opção).... Melhor ainda, é incluir
/dev/null
como primeiro arquivo a pesquisar. Isso resolve dois problemas:grep
pensará que existem dois e use o modo de saída de vários arquivos.grep
pensará que existe um arquivo e não ficará esperando no stdin.Portanto, a resposta final é:
fonte
find
em uma substituição de comando. Isso é interrompido se houver nomes de arquivos contendo espaços ou outros caracteres especiais. Usefind -exec
, é robusto e fácil de usar.find -iname "*target*" -or -name 'exclude' -prune
. Bem, isso meio que funciona - o diretório removido será listado, mas não será pesquisado. Se você não quer que ele na lista, você pode acrescentar uma espécie de redundância! -name 'exclude'