O mais fácil seria ativar a globalização recursiva de arquivos, por exemplo, no Bash:
shopt -s globstar
for f in **/*.*; do
type=$(file "$f" | tr "[A-Z]" "[a-z]" | awk '{print $2}')
mv -- "$f" "${f%.*}.$type"
done
Dessa forma, você evita ter que analisar find output. O problema é que, se houver muitos arquivos, esse comando poderá falhar, pois poderá exceder o tamanho máximo de uma linha de comando. Isso ocorre porque os nomes dos arquivos em **/*.* serão expandidos pelo Bash antes que o comando seja executado.
Portanto, a alternativa é usar find , direcionando sua saída para while e read .
find . -type f -print0 | while IFS= read -r -d '' f
type=$(file "$f" | tr "[A-Z]" "[a-z]" | awk '{print $2}')
mv -- "$f" "${f%.*}.$type"
done
Para algumas práticas recomendadas que funcionam com listas de arquivos, consulte: link