Estou tentando encontrar todos os arquivos que são de um determinado tipo e não contêm uma determinada string. Eu estou tentando fazer isso encanando encontrar 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 no SessionPb.java) e que não possuem um 'estende SomethingSomething "dentro dele.
Minha suspeita é que estou fazendo errado. Então, como deve ser o comando?
Respostas:
Não há necessidade
xargs
aqui. Também é necessário usargrep
com a-L
opção (arquivos sem correspondência), pois, caso contrário, ele exibirá o conteúdo do arquivo em vez de seu nome, como no seu exemplo.fonte
-L
já tem negociação, porque significafiles _without_ match
. Portanto, você não precisa de-v
opção aqui.find -exec \+
alguém me escreve que é muito melhor usar xargs. por que ninguém parece homem antes de escrever um comentário? (:-exec ... {} \+
não é equivalente axargs
. Por favor, leia a documentação do findutils! (Eu trabalhei muito duro para isso!)xargs
processa sua entrada e separa argumentos no espaço em branco. As cotações também são especiais (por padrão) paraxargs
. Nenhuma dessas coisas é verdadeira-exec ... {} +
. As versões antigasxargs
costumavam considerar o sublinhado como um indicador EOF, mas esse não é mais o caso.Você quase entendeu mesmo ...
O ponto '.' diz para começar a partir daqui. (o seu implica ... mas nunca assuma).
-iname usa pesquisa sem distinção entre maiúsculas e minúsculas, apenas no caso (ou apenas no caso não).
-print0 envia nomes de arquivos para xargs com um caractere \ x00 à direita, o que evita problemas com nomes de arquivos com espaços neles.
o '-0' no xargs diz esperar nomes de arquivos que terminem com \ x00 em vez de retornos.
e seu comando grep ...
Praticamente entendi.
EDITAR::
Na sua atualização:
deve ajudar. (Adicionado -L da resposta do @ rush, bom trabalho)
Tenho a ideia de que seu grep precisa da opção '-i' ou para ser menos explícito.
Tente o comando em partes ... ESTE nome de arquivo de saída parece adequado?
Nesse caso, é provável que o seu problema seja o padrão de pesquisa grep (erro de ortografia? Acontece!) Ou simplesmente não há correspondências.
Pior caso absoluto:
fará muito mais trabalho pesquisando tudo, mas deverá fornecer alguma saída.
fonte
xargs -0 grep -v "something something"
deve serxargs -0 grep -v "something something" /dev/null
caso contrário você terá resultados estranhos quando find não produz arquivos correspondentes.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êmsomething something
. Por exemplo, ele imprime duas linhas entre as três seguintes:Para imprimir arquivos que não contêm
extends SomethingSomething
nenhum lugar, use a-L
opção:Algumas versões do grep não têm a
-L
opção (não é especificada pelo POSIX ). Se o seu não for, imprima nada e use o código de retorno para que o shell de chamada faça o que deve ser feito.Como alternativa, use awk.
No Linux ou Cygwin (ou outro sistema com GNU grep), você não precisa usá-lo
find
, poisgrep
é capaz de se repetir.Se seu shell for ksh, bash ou zsh, você poderá fazer com que o shell faça o nome do arquivo correspondente. No bash, execute
set -o globstar
primeiro (você pode colocar isso no seu~/.bashrc
).fonte
\s
é uma extensão GNU grep, que eu acho que é sinônimo[[:space:]]
.