Como posso o grep não imprimir erros 'Não existe esse arquivo ou diretório'?


215

Estou fazendo grepping através de uma grande pilha de código gerenciado pelo git, e sempre que faço um grep, vejo pilhas e pilhas de mensagens do formulário:

> grep pattern * -R -n
whatever/.git/svn: No such file or directory

Existe alguma maneira de fazer essas linhas desaparecerem?


1
Hoje em dia eu recomendo usar ag, ackou, em cgrepvez disso - eles são muito mais rápidos / melhores do que greppara pesquisar repositórios de código.
precisa saber é o seguinte

Se você está pesquisando o código e procurando evitar diretórios específicos, talvez deva procurar ack. É um grep com reconhecimento de código-fonte e, como tal, ignorará ativamente esses diretórios VCS (assim como backups do vi e emacs, arquivos não-fonte etc.).
Brian Agnew

2
Como um usuário pode receber No such file or directorymensagens para arquivos e / ou diretórios existentes? Ou, inversamente, como grep *obter nomes de arquivos que não existem? Essa é uma condição de corrida, em que algum outro processo manipula a árvore de diretórios (criação, renomeação e exclusão de arquivos) enquanto ela grepestá em execução?
Scott

Respostas:


299

Você pode usar o sinalizador -sou --no-messagespara suprimir erros.

-s, --no-messages suprime mensagens de erro

grep pattern * -s -R -n

14
@Alex @Dogbert Isso responde à pergunta, mas '-s' pode mascarar problemas, por exemplo, quando você usa xargs com grep. Tente criar 2 arquivos em um diretório, 'aaa.txt' e 'a b.txt', ambos contendo a sequência 'some text'. O comando /bin/ls -1 | xargs grep 'some text'fornecerá "esse arquivo ou diretório", porque ele divide 'a b.txt' em 2 args. Se você suprimir, não notará que perdeu um arquivo.
Kelvin

@ Kelvin sim, por exemplo, se eu usar finde usar print0com xargs -0Isso resolve o problema? Obrigado
Luka

1
@Luka Isso deve resolver o problema. Você não terá problemas se sempre usar essas opções NUL, mas se não o fizer, é quase garantido (IMHO) que você esquecerá no momento mais inoportuno.
Kelvin

Isso funciona em Mac OS X, onde outras opções (--quiet) Não
philshem

59

Se você está procurando através de um repositório git, eu recomendo que você use git grep. Você não precisa passar -Rou o caminho.

git grep pattern

Isso mostrará todas as correspondências do seu diretório atual para baixo.


5
+1 para o útil comando específico do git. Não vai funcionar para o SVN embora :-)
cadrian

2
+1 Este é o comando git que estou perdendo - isso permite que eu receba uma string do estado da árvore em qualquer commit (adicionando o commit após o "padrão").
Kelvin

1
Com o plug-in fugitivo, Ggreptambém pesquisa a partir da parte superior do diretório Git, em vez do diretório atual.
Ciro Santilli escreveu

Parece ser significativamente mais rápido que o grep padrão. (Talvez ele ignora arquivos binários, etc idéia, mas útil?.)
Daniel

10

Erros como esse geralmente são enviados para o fluxo de "erro padrão", que você pode canalizar para um arquivo ou simplesmente desaparecer na maioria dos comandos:

grep pattern * -R -n 2>/dev/null

Responde à pergunta, mas pode mascarar problemas. Veja meu comentário na resposta de Dogbert.
Kelvin

5

Eu já vi isso acontecer várias vezes, com links quebrados (links simbólicos que apontam para arquivos que não existem), o grep tenta pesquisar no arquivo de destino, que não existe (daí a mensagem de erro correta e precisa).

Normalmente, eu não me incomodo ao executar tarefas sysadmin no console, mas, a partir dos scripts, procuro arquivos de texto com "find" e depois grep cada um:

find /etc -type f -exec grep -nHi -e "widehat" {} \;

Ao invés de:

grep -nRHi -e "widehat" /etc

4

Normalmente, não deixo o grep fazer a recursão em si. Geralmente, existem alguns diretórios que você deseja pular (.git, .svn ...)

Você pode fazer aliases inteligentes com posturas como essa:

find . \( -name .svn -o -name .git \) -prune -o -type f -exec grep -Hn pattern {} \;

Pode parecer um exagero à primeira vista, mas quando você precisa filtrar alguns padrões, é bastante útil.


1
+1. Isso é muito melhor do que suprimir erros. No entanto, acho que você esqueceu o -execantes do seu grep.
Kelvin

1
O que isto significa? \( -name .svn -o -name .git \)
Sbhatla

Por que não usar os sinalizadores grex --exclude ou --exlcude-dir?
Choylton B. Higginbottom

1
@sbhatla os parênteses criam uma ordem de operações para o comando find. stackoverflow.com/questions/24338777/…
Choylton B. Higginbottom

4

Você já tentou a -0opção em xargs ? Algo assim:

ls -r1 | xargs -0 grep 'some text'

2
para encontrar você deve adicionar -print0find -print0 | xargs -0 grep 'text'
aliva

1

Use -Iem grep.

Exemplo: grep SEARCH_ME -Irs ~/logs.


1
-Ipula arquivos binários - é equivalente a --binary-files=without-match. Ele não suprime as mensagens "Não existe esse arquivo ou diretório".
Mkfearnley

0

I redirecionar stderrpara stdoute, em seguida, inverter-match uso de grep ( -v) para excluir a string de aviso / erro que eu quero esconder:

grep -r <pattern> * 2>&1 | grep -v "No such file or directory"
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.