Em:
zsh -c "autoload zmv; zmv -f '(*).JPG' '$1.jpg'"
O $1 é entre aspas duplas, portanto, expandido pelo seu shell ( bash ), provavelmente para a string vazia, então zsh acaba interpretando:
autoload zmv; zmv -f '(*).JPG' '.jpg'
Uso:
zsh -c "autoload zmv && zmv '(*).JPG' '\.jpg'"
Em que a barra invertida cita o $ para bash para remover seu significado especial entre aspas duplas.
Você também pode fazer:
zsh -c "autoload zmv && zmv '(*).(#i)jpg' '\.jpg'"
Em que (#i) deve ativar a correspondência sem distinção entre maiúsculas e minúsculas, para que também renomeie os arquivos .Jpg , .JPg , .jpG ....
Você também pode fazer isso funcionar:
fix_ext_case() {
EXT=$1 zsh -c "autoload zmv && zmv \"(*).(#i)\$EXT\" '\.\$EXT'"
}
Ou com uma combinação diferente de citações:
fix_ext_case() {
EXT=$1 zsh -c 'autoload zmv && zmv "(*).(#i)$EXT" "\.\$EXT"'
}
Para ser usado como:
fix_ext_case jpg
ou
fix_ext_case png
(ou fix_ext_case JPG se você deseja converter em maiúsculas).