Ajuda para entender a sintaxe `find` no Solaris

Ajuda para entender a sintaxe `find` no Solaris

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 -execchamada. 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 -execpara acessar arquivos de hierarquia inferior? Eu sei que posso usar um forloop como este, mas estou curioso para saber se isso pode ser feito em uma findchamada:

$ 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.kshleva 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

  1. Na verdade, seu shell está se expandindo test[1-4]antes de ser invocado find. Você precisa escapar disso com'…'
  2. {}é tratado como padrão apenas quando é um token separado

-execem 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 md5sumde forma eficiente — com todos os nomes de arquivos fornecidos de uma só vez.

informação relacionada