É possível aninhar um 'find -exec' dentro de outro 'find -exec'?

12

Algo como o seguinte é o que eu estou procurando mas meu código não funciona, não importa como eu escape {} e + ;

find ./ -maxdepth 1 -type d -name '.*' -exec \
    find {} -maxdepth 1 -type f -name '*.ini' -exec \
        md5sum \{\} \; \;

Depois de ver este Pergunta Unix- & -Linux , Descobri que o código a seguir funciona, mas não está aninhando find como tal e suspeito que exista uma maneira melhor de executar esse trabalho específico.

find ./ -maxdepth 1 -type d -name '.*' \
-exec bash -c 'for x; do
    find "$x" -maxdepth 1 -type f -name "*.ini" \
    -exec md5sum \{\} \;; \
done' _ {} \+

Existe alguma maneira de aninhar find -exec sem a necessidade de invocar uma concha (como acima), com todas as suas restrições de citação e escape?

Ou isso pode ser feito diretamente em um único comando de localização, usando uma mistura de seus muitos parâmetros?

    
por Peter.O 05.08.2011 / 05:05

3 respostas

6

Eu tentaria usar um único anúncio como:

find .*/ -maxdepth 1 -type f -name '*.ini' -execdir md5sum {} +

ou mesmo (sem find , apenas globalização)

md5sum .*/*.ini

embora isso não tenha a verificação -type f , isso só funcionará se você não tiver diretórios / não-arquivos que terminem em .ini . Se você, você poderia usar

for x in .*/*.ini; do 
    if [ -f "$x" ]; then 
        md5sum "$x"
    fi
done

que, no entanto, perderia a vantagem de precisar apenas de uma invocação de md5sum.

Editar

Para um método geral e seguro de encadear find , você pode fazer algo como

find <paths> <args> -print0 | xargs -0 -I{.} find {.} <args for second find> [etc.]
    
por 05.08.2011 / 05:37
2

Seu problema original não exige a chamada de encontrar recursivamente, mas eu suponho que esse não era o ponto.

Eu acredito que não é possível chamar encontrar recursivamente da maneira que você deseja.

O seguinte não está chamando encontrar recursivamente (ou aninhamento, seja qual for o nome), mas você não pode simplesmente pegar um conjunto de resultados do primeiro achado e alimentá-lo ao segundo? É assim que eu faria instintivamente:

find 'find ./ -maxdepth 1 -type d -name '.*'' \
    -maxdepth 1 -type f -name '*.ini' -exec md5sum {} \;

Você também pode usar xargs para executar a segunda descoberta.

Atualização:

Eu queria adicionar isso, porque a maioria dos utilitários UNIX usa vários argumentos de nomes de arquivos em vez de um, geralmente você pode evitar o -exec :

md5sum 'find \'find ./ -maxdepth 1 -type d -name '.*'\' -maxdepth 1 -type f -name '*.ini''

Ao aninhar backticks, você adiciona barras invertidas \ antes das internas.

Se imaginarmos que md5sum leva apenas um argumento de nome de arquivo, sempre podemos envolvê-lo em um for loop:

for f in 'find \'find ./ -maxdepth 1 -type d -name '.*'\' -maxdepth 1 -type f -name '*.ini''
do
    md5sum $f
done

Observe que isso se torna mais difícil se os nomes de arquivos / diretórios que iniciam com - ou que contêm um espaço estiverem envolvidos. Os utilitários UNIX não funcionam bem com eles. Nesse caso, é necessário adicionar ./ , -- ou aspas.

Obviamente, o exemplo original não é bom, porque poderíamos apenas fazer:

md5sum .*/*.ini
    
por 05.08.2011 / 09:01
0

Pelo menos consegui aninhar 2 comandos de localização:

find ~ -maxdepth 1 -type d -name '.*' -execdir \
    find {} -maxdepth 1 -type f -name '*.ini' \;

Mas eu não resolvi invocar outro -exec (dir) - ligue de lá.

    
por 05.08.2011 / 11:20