Pipe encontrar em grep -v

Pipe encontrar em grep -v

Estou tentando encontrar todos os arquivos de um determinado tipo e que não contenham uma determinada string. Estou tentando fazer isso canalizando find para grep -v

exemplo:

find -type f -name '*.java' | xargs grep -v "something something"

Isso não parece funcionar. Parece estar apenas retornando todos os arquivos que o comando find encontrou. O que estou tentando fazer é basicamente encontrar todos os arquivos .java que correspondam a um determinado nome de arquivo (por exemplo, termina com 'Pb' como em SessionPb.java) e que não tenham um 'extends SomethingSomething' dentro dele.

Minha suspeita é que estou fazendo errado. Então, como deveria ser o comando?

Responder1

Não há necessidade xargsaqui. Além disso, você precisa usar a opção grepwith -L(arquivos sem correspondência), caso contrário, ele exibirá o conteúdo do arquivo em vez de seu nome, como no seu exemplo.

find . -type f -iname "*.java" -exec grep -L "something somethin" {} \+

Responder2

Você quase conseguiu, realmente...

find . -type f -iname "*.java" -print0 | xargs -0 grep -v "something something"

O ponto '.' diz para começar daqui. (o seu implica isso .. mas nunca presuma).

-inameusa pesquisa que não diferencia maiúsculas de minúsculas, apenas por precaução (ou simplesmente sem maiúsculas e minúsculas).
-imprimir0envia nomes de arquivos para xargs com um caractere \x00 final, o que evita problemas com nomes de arquivos contendo espaços.

o '-0' em xargs diz para esperar nomes de arquivos terminando em \x00 em vez de retornos.

e seu comando grep ...

Praticamente entendi.


EDITAR::

Da sua atualização:

find . -type f -iname "*pb.java" -print0 | xargs -0 grep -iL "something"

deveria ajudar. (Adicionado -L da resposta de @rush, bom trabalho)

Tenho a impressão de que o seu grep precisa da opção '-i' ou de ser menos explícito.

Tente o comando em partes... ESTE produz nomes de arquivos que parecem adequados?

find . -type f -iname "*pb.java"

Nesse caso, é provável que seu problema seja que seu padrão de pesquisa grep não corresponda (erro de ortografia? isso acontece!) Ou simplesmente não há correspondências.

Pior caso absoluto:

grep -riL "something" *

fará MUITO mais trabalho pesquisando tudo, mas deverá fornecer alguma saída.

Responder3

O computador está sendo um computador: está fazendo o que você mandou, em vez do que você queria que ele fizesse.

grep -v "something something"imprime todas as linhas que não contêm something something. Por exemplo, ele imprime duas linhas entre as três seguintes:

hello world
this is something something
something else

Para imprimir arquivos que não contêm extends SomethingSomethingnenhum lugar, use a -Lopção:

grep -L -E 'extends[[:space:]]+SomethingSomething' FILENAME…

Algumas versões do grep não possuem a -Lopção (não é especificada porPOSIX). Se o seu não imprimir, não imprima nada e use o código de retorno para que o shell de chamada faça o que for necessário.

grep -q -E 'extends[[:space:]]+SomethingSomething' FILENAME ||
echo "$FILENAME"

Alternativamente, use awk.

awk '
    FNR == 1 && NR != 1 && !found { print fn }
    FNR == 1 { fn = FILENAME; found = 0; }
    /extends[[:space:]]+SomethingSomething/ { found = 1 }
    END { if (fn != "" && !found) print fn }
'

No Linux ou Cygwin (ou outro sistema com GNU grep), você não precisa usar find, pois grepé capaz de ser recursivo.

grep -R --include='*.java' -L -E 'extends[[:space:]]+SomethingSomething'

Se o seu shell for ksh ou bash ou zsh, você pode fazer com que o shell faça a correspondência do nome do arquivo. No bash, execute set -o globstarprimeiro (você pode colocar isso no seu arquivo ~/.bashrc).

grep -L -E 'extends[[:space:]]+SomethingSomething' **/*.java

Responder4

find -type f -name '*.java' 2>&1 | grep -v "something something"

o que você está "exibindo" é exibido no stderr, não no stdout.

o comando acima redireciona stderr para stdout

Fonte

informação relacionada