Antecedentes
Eu estava curioso para saber se conseguiria uma solução que alcançasse dois objetivos:
- mais fácil de ler
- mais fácil de depurar
Construindo a maravilhosa resposta de @kusalananda a este outro Q & A de Q & A intitulado: Compreendendo a opção -exec de find
, acho que descobri algo que resolve seu problema.
Para começar, aqui está minha estrutura de diretório de amostra que imita a sua.
$ mkdir -p Artist{1..5}/Album{1..5}
$ touch Artist{1..5}/Album{1..5}/Track{1..5}.mp3
Isso resulta no seguinte:
$ find Artist* -type f | head
Artist1/Album1/Track1.mp3
Artist1/Album1/Track2.mp3
Artist1/Album1/Track3.mp3
Artist1/Album1/Track4.mp3
Artist1/Album1/Track5.mp3
Artist1/Album2/Track1.mp3
Artist1/Album2/Track2.mp3
Artist1/Album2/Track3.mp3
Artist1/Album2/Track4.mp3
Artist1/Album2/Track5.mp3
Agora, copie seus arquivos de mp3 para ./targetDir
:
$ find . -type f -name '*.mp3' -exec sh -c \
'cp {} targetDir/$(echo "{}" | sed "s#\./##g;s#/#-#g")' \;
O que resulta disso:
$ ls targetDir/ | head
Artist1-Album1-Track1.mp3
Artist1-Album1-Track2.mp3
Artist1-Album1-Track3.mp3
Artist1-Album1-Track4.mp3
Artist1-Album1-Track5.mp3
Artist1-Album2-Track1.mp3
Artist1-Album2-Track2.mp3
Artist1-Album2-Track3.mp3
Artist1-Album2-Track4.mp3
Artist1-Album2-Track5.mp3
Eu gosto dessa abordagem, porque posso envolver o comando cp ...
em echo
primeiro para poder verificar a saída antes de confirmar o trabalho:
$ find . -type f -name '*.mp3' -exec sh -c \
'echo "cp {} targetDir/$(echo "{}" | sed "s#\./##g;s#/#-#g")"' \;
cp ./Artist1/Album1/Track1.mp3 targetDir/Artist1-Album1-Track1.mp3
cp ./Artist1/Album1/Track2.mp3 targetDir/Artist1-Album1-Track2.mp3
cp ./Artist1/Album1/Track3.mp3 targetDir/Artist1-Album1-Track3.mp3
cp ./Artist1/Album1/Track4.mp3 targetDir/Artist1-Album1-Track4.mp3
cp ./Artist1/Album1/Track5.mp3 targetDir/Artist1-Album1-Track5.mp3
cp ./Artist1/Album2/Track1.mp3 targetDir/Artist1-Album2-Track1.mp3
cp ./Artist1/Album2/Track2.mp3 targetDir/Artist1-Album2-Track2.mp3
cp ./Artist1/Album2/Track3.mp3 targetDir/Artist1-Album2-Track3.mp3
cp ./Artist1/Album2/Track4.mp3 targetDir/Artist1-Album2-Track4.mp3
...
Como funciona
Esta solução recebe a saída de find
e, em seguida, executa o seguinte comando shell:
cp {} targetDir/$(echo "{}" | sed "s#\./##g;s#/#-#g")'
Isso irá cp
do arquivo de Artist../Album../Track..
para targetDir/..
e reformulará o nome para que ele tenha traços ( -
) onde há uma barra ( /
).
NOTA: adicionei 2 operações ao sed
. A primeira tira qualquer prefixo ./
que possa existir se você usar find . ...
em vez de find Artist* ..
.
Alternativas?
Acho que fazer isso usando find
e cp
ainda não é a solução ideal. Eu também mantenho diretórios de arquivos MP3 e acho que fazer algo parecido com rsync
e através de listas que você fornece rsync
pode ser uma implementação mais útil, mais longo desde que você pode usá-lo para atualizar, em vez de copiar cada vez que você executá-lo.
$ man rsync
...
--files-from=FILE read list of source-file names from FILE
Apenas um pensamento.