
Copiei em lote meus CDs antigos para Track1.mp3. O problema é que cada diretório de CD possui Track1.mp3, então quando eu os movo para /Music, eles sobrescrevem!
Existe possivelmente um script bash ou comando mv paramover.mp3s de vários subdiretórios com o mesmo nome de arquivo em um único diretório enquanto os renomeia se esse nome já existir no LINUX?
Responder1
Provavelmente você desejará renomeações "amigáveis". Vamos supor que você tenha uma sutura como
Artist1-+
+-AlbumA-+
| +-Track1.mp3
| +-Track2.mp3
+-AlbumB-+
+-Track1.mp3
+-Track2.mp3
Artist2-+
+-AlbumX-+
| +-Track1.mp3
| +-Track2.mp3
+-AlbumY-+
| +-Track1.mp3
| +-Track2.mp3
Agora você gostaria que o diretório único contivesse algo como
Artist1-AlbumA-Track1.mp3
Artist1-AlbumA-Track2.mp3
...
Artist2-AlbumY-Track1.mp3
Artist2-AlbumY-Track2.mp3
Isto pode ser conseguido com um simples bash
loop
for M in */*/*.mp3; do
TRACK=$(basename "$M")
ALBUM=$(basename $(dirname "$M"))
ARTIST=$(basename $(dirname $(dirname "$M")))
mv "$M" "$TARGET_DIR/$ARTIST-$ALBUM-$TRACK"
done
Responder2
Os comandos cp
e mv
suportam esta funcionalidade através da --backup
opção.
Demanual:
--backup[=CONTROL] make a backup of each existing destination file -b like --backup but does not accept an argument
[...]
O sufixo de backup é '~', a menos que seja definido com --suffix ou SIMPLE_BACKUP_SUFFIX. O método de controle de versão pode ser selecionado através da opção --backup ou através da variável de ambiente VERSION_CONTROL. Aqui estão os valores:
none, off never make backups (even if --backup is given) numbered, t make numbered backups existing, nil numbered if numbered backups exist, simple otherwise simple, never always make simple backups
Então, por exemplo, mv --backup=t <source_file> <dest_file>
deve funcionar.
Responder3
De acordo com a comunidade Linux e commandlinefu.com, esse recurso conveniente não é possível em nenhuma versão até o momento.
Atualmente não há comando e nenhuma maneira segura, via linha de comando, de mover arquivos de vários diretórios e subdiretórios com o mesmo nome, para um único diretório, sem substituí-los.
Fontes: commandlinefu.com, askubuntu.com, linuxquestions.org, superuser.com
Responder4
Presumo que você tenha uma estrutura de pastas como esta:
$ tree .
.
├── artist1
│ ├── albuma
│ │ └── Track1.mp3
│ └── albumb
│ └── Track1.mp3
└── artist two
├── album one
│ └── Track1.mp3
└── album two
└── Track1.mp3
Primeiro, cd
para a pasta pai da sua coleção de MP3 (pasta pai de artist1
).
Agora, se você executar o seguinte find
comando, verá uma saída como esta:
$ find . -name '*.mp3' -exec bash -c 'echo mv -v "$1" /tmp/music/$(echo "$1" | sed "s/\.\///" | tr " /" "-")' bash {} \;
mv -v ./artist two/album one/Track1.mp3 /tmp/music/artist-two-album-one-Track1.mp3
mv -v ./artist two/album two/Track1.mp3 /tmp/music/artist-two-album-two-Track1.mp3
mv -v ./artist1/albuma/Track1.mp3 /tmp/music/artist1-albuma-Track1.mp3
mv -v ./artist1/albumb/Track1.mp3 /tmp/music/artist1-albumb-Track1.mp3
find
coleta todos os caminhos para os arquivos MP3, por exemplo,./artist two/album one/Track1.mp3
e os passabash
via-exec
$(echo "$1" | sed "s/\.\///" | tr " /" "-")
é usado para modificar o nome do arquivo de saída.sed
remove o primeiro./
etr
converte todos os caracteres de espaço e/
para-
.
É essencial que você execute find
como .
diretório inicial, caso contrário o caminho de saída (relativo) não será modificado corretamente. Mude /tmp/music/
para o caminho da sua biblioteca de música.
Se a saída parecer boa para você, remova a primeira echo
e execute o comando novamente.
Saída:
$ find . -name '*.mp3' -exec bash -c 'mv -v "$1" /tmp/music/$(echo "$1" | sed "s/\.\///" | tr " /" "-")' babbsh {} \;
'./artist two/album one/Track1.mp3' -> '/tmp/music/artist-two-album-one-Track1.mp3'
'./artist two/album two/Track1.mp3' -> '/tmp/music/artist-two-album-two-Track1.mp3'
'./artist1/albuma/Track1.mp3' -> '/tmp/music/artist1-albuma-Track1.mp3'
'./artist1/albumb/Track1.mp3' -> '/tmp/music/artist1-albumb-Track1.mp3'