Não tenho ideia de por que a primeira solução da sua pergunta não funcionaria. Eu só posso supor que você esqueceu de remover o echo . Seja como for, aqui está outra abordagem que também deve fazer o que você precisa, supondo que esteja executando bash :
shopt -s globstar
for i in **/*jpg; do mv "$i" "${i//\//_}"; done
Explicação
- O
shopt -s globstarativa o recursoglobstardo bash, o que torna**recursivamente igual a qualquer número de diretórios ou arquivos. -
for i in **/*jpg;irá iterar todos os arquivos (ou diretórios) cujos nomes terminem em.jpg, salvando cada um como$i. -
"${i//\//_}"é o nome do arquivo (ou diretório) atual com todas as instâncias de/substituídas por_.
Se você também tiver diretórios com nomes terminados em .jpg e quiser ignorá-los, faça isso:
shopt -s globstar
for i in **/*jpg; do [ -f "$i" ] && echo mv "$i" "${i//\//_}"; done
E para todos os arquivos, independentemente da extensão:
shopt -s globstar
for i in **/*; do [ -f "$i" ] && echo mv "$i" "${i//\//_}"; done