
Considere os seguintes arquivos:
$ find findtest
findtest
findtest/test1
findtest/test1/start.ksh
findtest/test2
findtest/test2/start.ksh
findtest/test3
findtest/test3/start.ksh
findtest/test4
findtest/test4/start.ksh
Minha dúvida é sobre o uso de {}
na -exec
chamada. Funciona como eu esperava ao designar o arquivo de resultado:
$ find findtest -name test[1-4] -exec ls -d {} \;
findtest/test1
findtest/test2
findtest/test3
findtest/test4
No entanto, não parece ser expandido quando usado em um caminho:
$ find findtest -name test[1-4] -exec md5sum {}/start.ksh \;
md5sum: {}/start.ksh: No such file or directory
md5sum: {}/start.ksh: No such file or directory
md5sum: {}/start.ksh: No such file or directory
md5sum: {}/start.ksh: No such file or directory
Como posso usar find -type d -exec
para acessar arquivos de hierarquia inferior? Eu sei que posso usar um for
loop como este, mas estou curioso para saber se isso pode ser feito em uma find
chamada:
$ for f in $(find findtest -name test[1-4]); do md5sum "$f"/start.ksh; done
d41d8cd98f00b204e9800998ecf8427e findtest/test1/start.ksh
d41d8cd98f00b204e9800998ecf8427e findtest/test2/start.ksh
d41d8cd98f00b204e9800998ecf8427e findtest/test3/start.ksh
d41d8cd98f00b204e9800998ecf8427e findtest/test4/start.ksh
Responder1
OPadrão POSIX para o comando findexige apenas que um {} isolado seja substituído pelo nome do arquivo, e apenas o primeiro. Usar {}/start.ksh
leva a comportamento não especificado.
Um argumento contendo apenas os dois caracteres "{}" deve ser substituído pelo conjunto de nomes de caminho agregados, com cada nome de caminho passado como um argumento separado para o utilitário invocado na mesma ordem em que foi agregado. O tamanho de qualquer conjunto de dois ou mais nomes de caminho deve ser limitado de modo que a execução do utilitário não faça com que o limite {ARG_MAX} do sistema seja excedido. Se mais de um argumento contendo apenas os dois caracteres "{}" estiver presente, o comportamento não será especificado.
Se um nome_do_utilitário ou uma sequência de argumentos contiver os dois caracteres "{}", mas não apenas os dois caracteres "{}", será definido pela implementação se find substituirá esses dois caracteres ou usará a sequência sem alterações.
Uma maneira de fazer o que você deseja com o Solaris find seria esse comando:
find findtest -name "test[1-4]" -exec sh -c 'md5sum $1/start.ksh' foo {} \;
Uma maneira mais rápida seria:
find findtest -name "test[1-4]" -exec sh -c 'for i; do md5sum "$i/start.ksh"; done' foo {} +
Responder2
- Na verdade, seu shell está se expandindo
test[1-4]
antes de ser invocadofind
. Você precisa escapar disso com'…'
{}
é tratado como padrão apenas quando é um token separado
-exec
em si é geralmente caro e recomendado para ser usado com arrasto +
ou evitado em favor da alimentação xargs
.
Eu sei que posso usar um loop for como este, mas estou curioso para saber se isso pode ser feito em uma chamada find:
find findtest -name 'test[1-4]' -print0 | xargs -0I{} -- md5sum '{}/start.ksh'
— funciona md5sum
de forma eficiente — com todos os nomes de arquivos fornecidos de uma só vez.