Linux: Dateien mit gleichem Namen aus verschiedenen Verzeichnissen in ein einziges verschieben und dabei umbenennen

Linux: Dateien mit gleichem Namen aus verschiedenen Verzeichnissen in ein einziges verschieben und dabei umbenennen

Ich habe meine alten CDs stapelweise in Track1.mp3 gerippt. Das Problem ist, dass jedes CD-Verzeichnis Track1.mp3 hat. Wenn ich sie also nach /Music verschiebe, werden sie überschrieben!

Gibt es möglicherweise ein Bash-Skript oder einen MV-Befehl, umbewegen.mp3s aus mehreren Unterverzeichnissen mit demselben Dateinamen in ein einziges Verzeichnis kopieren und dabei umbenennen, wenn dieser Name unter LINUX bereits existiert?

Antwort1

Höchstwahrscheinlich möchten Sie "freundliche" Umbenennungen. Nehmen wir an, Sie haben eine Schlagzeile wie

Artist1-+
        +-AlbumA-+
        |        +-Track1.mp3
        |        +-Track2.mp3
        +-AlbumB-+
                 +-Track1.mp3
                 +-Track2.mp3
Artist2-+
        +-AlbumX-+
        |        +-Track1.mp3
        |        +-Track2.mp3
        +-AlbumY-+
        |        +-Track1.mp3
        |        +-Track2.mp3

Sie möchten nun, dass das einzelne Verzeichnis etwas wie Folgendes enthält:

Artist1-AlbumA-Track1.mp3
Artist1-AlbumA-Track2.mp3
...
Artist2-AlbumY-Track1.mp3
Artist2-AlbumY-Track2.mp3

bashDies kann mit einer einfachen Schleife erreicht werden

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

Antwort2

Die Befehle cpund mvunterstützen diese Funktionalität durch die --backupOption.

Von demHandbuch:

   --backup[=CONTROL]
          make a backup of each existing destination file

   -b     like --backup but does not accept an argument

[...]

Das Backup-Suffix ist „~“, sofern es nicht mit --suffix oder SIMPLE_BACKUP_SUFFIX festgelegt wurde. Die Versionskontrollmethode kann über die Option --backup oder über die Umgebungsvariable VERSION_CONTROL ausgewählt werden. Hier sind die Werte:

   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

Also mv --backup=t <source_file> <dest_file>sollte zB funktionieren.

Antwort3

Laut der Linux-Community und commandlinefu.com ist diese praktische Funktion in keiner der bisherigen Versionen überhaupt möglich.

Derzeit gibt es keinen Befehl und keine sichere Möglichkeit über die Befehlszeile, Dateien aus mehreren Verzeichnissen und Unterverzeichnissen mit demselben Namen in ein einziges Verzeichnis zu verschieben, ohne sie zu überschreiben.

Quellen: commandlinefu.com, askubuntu.com, linuxquestions.org, superuser.com

Antwort4

Ich gehe davon aus, dass Sie eine Ordnerstruktur wie diese haben:

$ tree .
.
├── artist1
│   ├── albuma
│   │   └── Track1.mp3
│   └── albumb
│       └── Track1.mp3
└── artist two
    ├── album one
    │   └── Track1.mp3
    └── album two
        └── Track1.mp3

Zunächst cdzum übergeordneten Ordner Ihrer MP3-Sammlung (übergeordneter Ordner von artist1).

Wenn Sie jetzt den folgenden Befehl ausführen find, erhalten Sie eine Ausgabe wie diese:

$ 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
  • findsammelt alle Pfade zu den MP3-Dateien ./artist two/album one/Track1.mp3und übergibt sie an bashvia-exec
  • $(echo "$1" | sed "s/\.\///" | tr " /" "-")wird verwendet, um den Ausgabedateinamen zu ändern. sedEntfernt das erste ./und trkonvertiert alle Leerzeichen und /in -.

Wichtig ist, dass Sie als Startverzeichnis verwenden find, .da sonst der (relative) Ausgabepfad nicht korrekt geändert wird. Wechseln Sie hier /tmp/music/zum Pfad Ihrer Musikbibliothek.

Wenn die Ausgabe für Sie gut aussieht, entfernen Sie das erste echound führen Sie den Befehl erneut aus.

Ausgabe:

$ 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'

verwandte Informationen