Estou tentando executar o seguinte comando:
find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' +
Isso está retornando um erro:
find: missing argument to -exec
Não vejo o que há de errado com este comando, pois parece corresponder à página de manual:
comando -exec {}
Essa variante da opção -exec executa o comando especificado nos arquivos selecionados, mas a linha de comando é criada anexando cada nome de arquivo selecionado no final; o número total de invocações do comando será muito menor que o número de arquivos correspondentes. A linha de comando é construída da mesma maneira que o xargs cria suas linhas de comando. Somente uma instância de '{}' é permitida dentro do comando. O comando é executado no diretório inicial.
Eu também tentei:
find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar {} +
find a/folder b/folder -name *.c -o -name *.h -exec 'grep -I foobar' {} +
find a/folder b/folder -name *.c -o -name *.h -exec 'grep -I foobar' '{}' +
find a/folder b/folder -name "*.c" -o -name "*.h" -exec grep -I foobar '{}' +
find a/folder b/folder \( -name *.c -o -name *.h \) -exec grep -I foobar '{}' +
find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+
+
do final?find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+
find
. Embora a-exec cmd {} +
variante seja POSIX e esteja disponível desde os anos 80, o GNU encontrou apenas a adição (relativamente) recentemente (2005). O quefind --version
te diz?-exec {} +
foi adicionado em 4.2.12 em 2005. Nos achados mais antigos do GNU, você pode usar o (não POSIX)-print0 | xargs -r0
para obter algo semelhante.4.1
é de 1994.-name
argumentos padrão deve ser citado:-name "*.c" -o -name "*.h"
. Isso é verdade, embora não esteja relacionado ao-exec
erro. Você notará que todas as outras respostas colocam os curingas entre aspas, embora apenas Gilles o mencione. … (Continua)-name "*.[ch]"
sem explicação. Isso tem os benefícios de simplificar a linha de comando e, especificamente, eliminar o-o
.-o
É difícil encontrar expressões que envolvam isso. O seu está errado; se o seu comando for corrigido para não causar erros (como na resposta de Gilles), ele será executadogrep
apenas nos.h
arquivos. Você precisa fazer'(' -name '*.c' -o -name '*.h' ')'
.Respostas:
Você precisa remover as aspas simples que você usa
{}
. O comando pode ser simplificado assim:Se você usa uma versão arcaica do GNU find, isso ainda deve funcionar:
fonte
{}
não têm significado específico para o shell."Falta de argumento para
-exec
" normalmente significa que o argumento para -exec
está faltando seu terminador. O terminador deve ser um argumento contendo apenas o caractere;
(que precisa ser citado em um comando shell, portanto, normalmente é escrito\;
ou';'
) ou dois argumentos sucessivos contendo{}
e+
.Stephane Chazelas identificou que você está usando uma versão mais antiga do GNU find, que não suporta
-exec … {} +
apenas-exec {} \;
. Embora o GNU tenha adotado tardiamente-exec … {} +
, eu recomendo que você obtenha um conjunto de ferramentas menos antigo (como o Cygwin , que inclui git e muito mais, ou o GNUwin32 , que não possui git, mas não tem a tentativa de mau funcionário -para-usar-linux-mas-nós-impomos-vibe Windows que Cygwin dá). Este recurso foi adicionado na versão 4.2.12, mais de 9 anos atrás (foi o último recurso identificado para tornar o GNUfind
POSIX compatível).Se você deseja manter uma localização antiga do GNU, pode usar
-print0
comxargs -0
para obter uma funcionalidade semelhante: execução de comandos agrupados, suportando nomes de arquivos arbitrários.Sempre cite os curingas na
find
linha de comando. Caso contrário, se você executar esse comando a partir de um diretório que contém.c
arquivos, o não citado*.c
será expandido para a lista de.c
arquivos no diretório atual.Adicionar
/dev/null
àgrep
linha de comando é um truque para garantir que o grep sempre imprima o nome do arquivo, mesmo quefind
encontre uma única correspondência. Com o GNU find, outro método é passar a opção-H
.fonte
Se um comando como
retorna erro
a causa provável é o GNU muito antigo,
find
que não suporta sintaxe-exec mycommand {} +
. Nesse caso, é necessário executar uma substituição de baixo desempenho,-exec mycommand {} \;
que executará omycommand
destino único para cada destino encontrado, em vez de coletar vários destinos e executar omycommand
apenas uma vez.No entanto, o GNU
find
não suporta, por exemplo,porque o GNU
find
suporta apenas combinações literais em{} +
vez de mais genéricas{} additional parameters +
. Observe que não pode haver nada entre os aparelhos e o+
personagem. Se você tentar isso, receberá o mesmo erro:A solução alternativa é usar a sintaxe
{} additional parameters \;
que funciona, mas executará o comando uma vez para cada destino encontrado. Se você precisar de mais desempenho com o GNU,find
precisará escrever um script de wrapper que possa acrescentar parâmetros adicionais aos argumentos fornecidos. Algo comodeve ser bom o suficiente. Ou, se você não deseja criar um arquivo temporário, pode usar uma linha para alterar a ordem dos parâmetros como esta:
que será executado
mycommand {list of ttf files} extra arguments
. Observe que pode ser necessário escape duplo de caracteres especiais para o bash após a-c
bandeira.fonte
find
, mas o comportamento correto especificado pelo POSIX .find
provavelmente o possuicp
. Nesse caso, você podefind ... -exec cp --target-directory ~/.fonts {} +
manter o{}
no final da sequência de execução.find . -type f -perm 0777 -exec chmod 644 {}\;
obteve erro
find: missing argument to ``-exec'
.Adicionando espaço entre
{}
e\
corrigido:find . -type f -perm 0777 -print -exec chmod 644 {} \;
fonte
find
comando na pergunta em questão.+
forma da-exec
opçãofind
. Esta resposta está corrigindo um problema que o usuário que está fazendo a pergunta não possui.Eu tive minha parcela de dores de cabeça com a sintaxe exec no passado. Na maioria dos dias, agora prefiro a sintaxe mais agradável do bash:
Existem algumas limitações quando você deseja tratar os arquivos como um grupo, pois cada um é avaliado em série, mas você pode canalizar a saída para outro local muito bem
fonte
find … -exec … \;
, portanto, não há razão para usá-lo, mesmo que você saiba que seus nomes de arquivo são mansos.exec
foi uma dor de cabeça durante os 5 minutos que eu queria gastar nisso. Meus nomes de arquivo eram mansos e isso resolveu meu problema :)