Você pode fazer isso com o GNU find
e o GNU mv
:
find /dir1 -mindepth 2 -type f -exec mv -t /dir1 -i '{}' +
Basicamente, da maneira que funciona, se isso find
percorre toda a árvore de diretórios e para cada arquivo ( -type f
) que não está no diretório de nível superior ( -mindepth 2
), ele executa um mv
para movê-lo para o diretório que você deseja ( -exec mv … +
). O -t
argumento para mv
permite especificar o diretório de destino primeiro, o que é necessário porque a +
forma de -exec
coloca todos os locais de origem no final do comando. O -i
faz mv
perguntar antes de substituir quaisquer duplicatas; você pode substituir -f
para substituí-los sem perguntar (ou -n
não perguntar ou substituir).
Como Stephane Chazelas aponta, o acima funciona apenas com ferramentas GNU (que são padrão no Linux, mas não na maioria dos outros sistemas). O seguinte é um pouco mais lento (porque chama mv
várias vezes), mas muito mais universal:
find /dir1 -mindepth 2 -type f -exec mv -i '{}' /dir1 ';'