Pipe encontra em grep -v

12

Estou tentando encontrar todos os arquivos que são de um determinado tipo e não contêm uma determinada string. Eu estou tentando ir em busca de piping ache 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 é de que estou fazendo errado. Então, como deve ser o comando?

    
por Hyangelo 05.07.2012 / 20:58

3 respostas

13

Não há necessidade de xargs aqui. Além disso, você precisa usar a opção grep with -L (arquivos sem correspondência), caso contrário, o conteúdo do arquivo será exibido em vez de seu nome, como em seu exemplo.

find . -type f -iname "*.java" -exec grep -L "something somethin" {} \+
    
por 05.07.2012 / 21:19
5

Você quase conseguiu ...

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

O ponto '.' diz para começar a partir daqui. (o seu implica ... mas nunca assuma).

-iname usa uma pesquisa sem distinção entre maiúsculas e minúsculas, apenas no caso (ou apenas em caso algum).
-print0 envia nomes de arquivos para xargs com um \ caractere x00, que evita problemas com nomes de arquivos com espaços neles.

o '-0' no xargs diz esperar nomes de arquivos terminando com \ x00 ao invés de retornos.

e seu comando grep ...

Quase entendi.

EDIT ::

Da sua atualização:

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

deve ajudar. (Adicionado -L da @ resposta do rush, bom trabalho)

Eu tenho a idéia de que o seu grep precisa da opção '-i' ou ser menos explícito.

Experimente o comando em partes ... NENHUM NOME DE NOME que parece adequado?

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

Em caso afirmativo, seu problema provavelmente é que o padrão de pesquisa do grep não está correspondendo (erro de ortografia? acontece!) ou simplesmente não há correspondências.

O pior caso absoluto:

grep -riL "something" *

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

    
por 05.07.2012 / 21:08
3

O computador está sendo um computador: ele está fazendo o que você mandou fazer 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, imprime duas linhas entre as três seguintes:

hello world
this is something something
something else

Para imprimir arquivos que não contenham extends SomethingSomething em qualquer lugar, use a opção -L :

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

Algumas versões do grep não têm a opção -L (não é especificado por POSIX ). Se o seu não tiver, imprima nada e use o código de retorno para fazer com que o shell de chamada faça o que for necessário.

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

Como alternativa, use o 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 o GNU grep), você não precisa usar find , pois grep é capaz de recorrer.

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

Se o seu shell é ksh ou bash ou zsh, você pode fazer o shell fazer a correspondência do nome do arquivo. No bash, execute set -o globstar primeiro (você pode colocar isso no seu ~/.bashrc ).

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

Tags