Ajuda a entender a sintaxe 'find' no Solaris

2

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 pergunta é sobre o uso de {} na chamada -exec . Ele funciona como eu esperaria 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, ele 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 o find -type d -exec para acessar arquivos de hierarquia inferiores? Eu sei que posso usar um loop for como este, mas estou curioso para saber se isso pode ser feito em uma chamada find :

$ 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
    
por rahmu 14.06.2012 / 12:01

2 respostas

5

O padrão POSIX para o comando de localização apenas exige que um {} isolado seja substituído por o nome do arquivo e apenas o primeiro. Usar {}/start.ksh leva a um comportamento não especificado.

An argument containing only the two characters "{}" shall be replaced by the set of aggregated pathnames, with each pathname passed as a separate argument to the invoked utility in the same order that it was aggregated. The size of any set of two or more pathnames shall be limited such that execution of the utility does not cause the system's {ARG_MAX} limit to be exceeded. If more than one argument containing only the two characters "{}" is present, the behavior is unspecified.

If a utility_name or argument string contains the two characters "{}", but not just the two characters "{}", it is implementation-defined whether find replaces those two characters or uses the string without change.

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 {} \;

Um caminho mais rápido seria:

find findtest -name "test[1-4]" -exec sh -c 'for i; do md5sum "$i/start.ksh"; done' foo {} + 
    
por 14.06.2012 / 13:36
-1
  1. Na verdade, seu shell está expandindo test[1-4] antes de invocar find . Você precisa escapar com '…'
  2. {} é tratado como padrão apenas quando está sendo um token separado

-exec em si é geralmente caro e recomendado para ser usado com trailing + , ou evitado em favor da alimentação xargs .

I know I can use a for loop like this, but I am curious to know if it can be done in one find call:

find findtest -name 'test[1-4]' -print0 | xargs -0I{} -- md5sum '{}/start.ksh' - executa md5sum de maneira eficiente - com todos os nomes de arquivo fornecidos de uma só vez.

    
por 14.06.2012 / 13:35

Tags