find . -type f -exec <command> '{}' \;
não é equivalente a
find . -type f | xargs <command>
observe:
$ find -type f
./b
./c
./e
./d
./a
$ find -type f -exec echo '{}' \;
./b
./c
./e
./d
./a
$ find -type f | xargs echo
./b ./c ./e ./d ./a
xargs
coleta vários argumentos até um determinado tamanho e, em seguida, executa o comando com todos os argumentos de uma só vez.
Isso é o que é executado a partir de find -type f -exec echo '{}' \;
echo ./b
echo ./c
echo ./e
echo ./d
echo ./a
Isso é o que é executado a partir de find -type f | xargs echo
echo ./b ./c ./e ./d ./a
Isso funciona bem para comandos que podem receber vários argumentos, como md5sum
ou file
. Mas não funciona para comandos que levam apenas um argumento por vez.
Para fazer com que xargs
se comporte mais como find -exec
, você pode adicionar o argumento -n1
a xargs
:
$ find -type f | xargs -n1 echo
./b
./c
./e
./d
./a
-n1
diz a xargs
para executar um comando para cada 1
de argumentos.
No seu comando de exemplo:
find . -type f -print0 | sort -Rz | xargs -0 -n1 <command>
Bônus: você também pode fazer com que find -exec
se comporte mais como xargs
fechando -exec
com \+
em vez de \;
:
find -type f -exec <command> '{}' \+