Estou procurando a string foo=
nos arquivos de texto em uma árvore de diretórios. Está em uma máquina Linux comum, tenho o shell bash:
grep -ircl "foo=" *
Nos diretórios também existem muitos arquivos binários que correspondem a "foo =". Como esses resultados não são relevantes e retardam a pesquisa, desejo que o grep pule a pesquisa desses arquivos (principalmente imagens JPEG e PNG). Como eu faria isso?
Eu sei que existem as opções --exclude=PATTERN
e --include=PATTERN
, mas qual é o formato do padrão? A página de manual do grep diz:
--include=PATTERN Recurse in directories only searching file matching PATTERN.
--exclude=PATTERN Recurse in directories skip file matching PATTERN.
A pesquisa no grep include , grep include exclude , grep exclude e as variantes não encontraram nada relevante
Se existe uma maneira melhor de grepping apenas em certos arquivos, sou a favor; mover os arquivos incorretos não é uma opção. Não consigo pesquisar apenas determinados diretórios (a estrutura de diretórios é uma grande bagunça, com tudo em todo lugar). Além disso, não consigo instalar nada, por isso tenho a ver com ferramentas comuns (como grep ou a localização sugerida ).
--exclude-dir=.svn
, então grep não vai para eles em tudogrep -r --exclude-dir=var "pattern" .
Respostas:
Use a sintaxe globbing do shell:
A sintaxe para
--exclude
é idêntica.Observe que a estrela é escapada com uma barra invertida para impedir que ela seja expandida pelo shell (citá-la, como
--include="*.{cpp,h}"
, também funcionaria). Caso contrário, se você tivesse algum arquivo no diretório de trabalho atual que correspondesse ao padrão, a linha de comando seria expandida para algo comogrep pattern -r --include=foo.cpp --include=bar.h rootdir
, que pesquisaria apenas arquivos nomeadosfoo.cpp
ebar.h
, o que provavelmente não é o que você queria.fonte
grep pattern -r --include="*.{cpp,h}" rootdir
grep pattern -r --include=foo.cpp --include=bar.h rootdir
que só pesquisará arquivos nomeadofoo.cpp
oubar.h
. Se você não possui nenhum arquivo que corresponda ao glob no diretório atual, o shell passa o glob para grep, que o interpreta corretamente.--exclude-dir
opção. As mesmas regras se aplicam. Somente o nome do arquivo do diretório é correspondido, não um caminho.--include
parece não funcionar depois--exclude
. Suponho que não faça sentido sequer tentar, exceto que eu tenhoalias
que grep com uma longa lista de--exclude
e--exclude-dir
, que eu uso para pesquisar código, ignorando bibliotecas e trocando arquivos e outras coisas. Eu teria esperado quegrep -r --exclude='*.foo' --include='*.bar'
iria trabalhar, para que eu pudesse limitar a minhaalias
a--include='*.bar'
única, mas parece ignorar o--include
e incluem tudo o que não é um arquivo .foo. Trocar a ordem do--include
e--exclude
funciona, mas, infelizmente, isso não é útil para o meualias
.PATTERN
. Metade da hora eu não consigo encontrar nenhuma descrição do que eles estão esperando lá paraSe você quiser apenas pular arquivos binários, sugiro que olhe para a opção
-I
(maiúscula i). Ele ignora arquivos binários. Eu uso regularmente o seguinte comando:Ele pesquisa recursivamente, ignora arquivos binários e não procura dentro das pastas ocultas do Subversion, por qualquer padrão que eu queira. Eu tenho o alias como "grepsvn" na minha caixa no trabalho.
fonte
--exclude-dir
não está disponível em qualquer lugar. minha caixa RH no trabalho com o GNU grep 2.5.1 não a possui.--exclude-dir
não estiver disponível? Em todas as minhas tentativas,--exclude
não parece se encaixar na conta.--exclude-dir="\.git"
,. :-)Por favor, dê uma olhada no ack , projetado para exatamente essas situações. Seu exemplo de
é feito com ack como
porque ack nunca procura em arquivos binários por padrão e -r está ativado por padrão. E se você quiser apenas arquivos CPP e H, faça
fonte
apt-get
no Ubuntu :)awk
O grep 2.5.3 introduziu o parâmetro --exclude-dir, que funcionará da maneira que você deseja.
Você também pode definir uma variável de ambiente: GREP_OPTIONS = "- exclude-dir = .svn"
Vou segundo Andy voto para ack , porém, é o melhor.
fonte
Descobri isso depois de muito tempo, você pode adicionar várias inclusões e exclusões como:
fonte
O comando sugerido:
está conceitualmente errado, porque --exclude funciona com o nome da base. Em outras palavras, ele ignorará apenas o .svn no diretório atual.
fonte
No grep 2.5.1, você deve adicionar esta linha ao perfil ~ / .bashrc ou ~ / .bash
fonte
Acho que a saída do grepping grep é muito útil às vezes:
No entanto, isso na verdade não impede a pesquisa nos arquivos binários.
fonte
grep -I
para pular arquivos binários.Se você não tem aversão ao uso
find
, eu gosto do seu-prune
recurso:Na primeira linha, você especifica o diretório que deseja pesquisar.
.
(diretório atual) é um caminho válido, por exemplo.Na 2ª e 3ª linhas, utilização
"*.png"
,"*.gif"
,"*.jpg"
, e assim por diante. Use tantas dessas-o -name "..." -prune
construções quanto os padrões.Na quarta linha, você precisa de outro
-o
(que especifique "ou" parafind
), os padrões que você deseja e precisa de um-print
ou-print0
no final dele. Se você quer apenas "tudo" o que resta após a poda a*.gif
,*.png
, etc. imagens, em seguida, usar-o -print0
e está feito com a linha 4.Finalmente, na quinta linha, está o canal no
xargs
qual cada um desses arquivos resultantes é armazenado em uma variávelFILENAME
. Em seguida, ele passagrep
os-IR
sinalizadores,"pattern"
eFILENAME
é expandidoxargs
para se tornar a lista de nomes de arquivos encontrados porfind
.Para sua pergunta em particular, a declaração pode ser algo como:
fonte
-false
imediatamente após cada-prune
assim esquecer de usar-print0
ou algum tipo deexec
comando não irá realmente imprimir os arquivos que você queria excluir:-name "*.png" -prune -false -o name "*.gif -prune -false
...No CentOS 6.6 / Grep 2.6.3, tenho que usá-lo assim:
Observe a falta de sinais de igual "=" (caso contrário
--include
,--exclude
,include-dir
e--exclude-dir
são ignorados)fonte
git grep
Uso
git grep
otimizado para desempenho e que visa pesquisar determinados arquivos.Por padrão, ele ignora arquivos binários e está honrando o seu
.gitignore
. Se você não está trabalhando com a estrutura do Git, ainda pode usá-lo passando--no-index
.Exemplo de sintaxe:
Para mais exemplos, consulte:
fonte
Eu sou um diletante, sem dúvida, mas eis a aparência do meu ~ / .bash_profile:
Observe que, para excluir dois diretórios, eu tive que usar --exclude-dir duas vezes.
fonte
Tente este:
Fundada aqui: http://www.unix.com/shell-programming-scripting/42573-search-files-excluding-binary-files.html
fonte
Se você pesquisar de forma não recursiva, poderá usar padrões glop para corresponder aos nomes dos arquivos.
inclui html e txt. Ele pesquisa apenas no diretório atual.
Para pesquisar nos subdiretórios:
Nos subsubdiretórios:
fonte
ripgrep
Essa é uma das ferramentas mais rápidas projetadas para pesquisar recursivamente seu diretório atual. Está escrito em Rust , construído sobre o mecanismo regex da Rust para máxima eficiência. Verifique a análise detalhada aqui .
Então você pode simplesmente executar:
Ele respeita o seu
.gitignore
e ignora automaticamente arquivos / diretórios ocultos e arquivos binários.Você ainda pode personalizar incluir ou excluir arquivos e diretórios usando
-g
/--glob
. Regras de globbing correspondem a.gitignore
globs. Procureman rg
ajuda.Para mais exemplos, consulte: Como excluir alguns arquivos que não correspondem a determinadas extensões com grep?
No macOS, você pode instalar via
brew install ripgrep
.fonte
find e xargs são seus amigos. Use-os para filtrar a lista de arquivos em vez de grep --exclude
Tente algo como
A vantagem de se acostumar com isso é que ele pode ser expandido para outros casos de uso, por exemplo, para contar as linhas em todos os arquivos não png:
Para remover todos os arquivos não png:
etc.
Conforme apontado nos comentários, se alguns arquivos tiverem espaços em seus nomes, use
-print0
-osxargs -0
.fonte
esses scripts não cumprem todo o problema ... Tente isso melhor:
esse script é muito melhor porque usa expressões regulares "reais" para evitar diretórios de pesquisa. basta separar os nomes de pastas ou arquivos com "\ |" no grep -v
Aproveite! encontrado no meu shell linux! XD
fonte
Veja @ este.
fonte
A
--binary-files=without-match
opção para o GNUgrep
faz com que ele pule arquivos binários. (Equivalente à-I
opção mencionada em outro lugar.)(Isso pode exigir uma versão recente do
grep
; 2.5.3, pelo menos.)fonte
adequado para o arquivo tcsh .alias:
Demorei um pouco para descobrir que a parte {mm, m, h, cc, c} NÃO deveria estar entre aspas. ~ Keith
fonte
Para ignorar todos os resultados binários do grep
A parte awk filtrará todo o arquivo binário foo corresponde às linhas
fonte
Tente o seguinte:
--F
" sob currdir .. (ou vincule outra pasta lá renomeada para "--F
" ou sejadouble-minus-F
.#> grep -i --exclude-dir="\-\-F" "pattern" *
fonte