Linux: перемещение файлов из разных каталогов с одинаковыми именами в один с одновременным переименованием

Linux: перемещение файлов из разных каталогов с одинаковыми именами в один с одновременным переименованием

Я скопировал свои старые CD в Track1.mp3. Проблема в том, что в каждом каталоге CD есть Track1.mp3, поэтому, когда я перемещаю их в /Music, они перезаписываются!

Возможно, есть скрипт bash или команда mv длядвигаться.mp3 из нескольких подкаталогов с одинаковым именем файла в один каталог, переименовывая их, если это имя уже существует в LINUX?

решение1

Скорее всего, вы захотите "дружественные" переименования. Предположим, у вас есть такая страйктура

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

Теперь вам нужно, чтобы в единственном каталоге содержалось что-то вроде

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

Этого можно добиться с помощью простого bashцикла

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

решение2

Команды cpи mvподдерживают эту функциональность с помощью --backupопции.

Изруководство:

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

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

[...]

Суффикс резервной копии — '~', если не задано с помощью --suffix или SIMPLE_BACKUP_SUFFIX. Метод управления версиями можно выбрать с помощью параметра --backup или через переменную среды VERSION_CONTROL. Вот значения:

   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

Так что, например, mv --backup=t <source_file> <dest_file>должно работать.

решение3

По данным сообщества Linux и commandlinefu.com, эта удобная функция невозможна ни в одной из версий на сегодняшний день.

В настоящее время не существует команды и надежного способа через командную строку перемещать файлы из нескольких каталогов и подкаталогов с одинаковыми именами в один каталог, не перезаписывая их.

Источники: commandlinefu.com, askubuntu.com, linuxquestions.org, superuser.com

решение4

Я предполагаю, что у вас такая структура папок:

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

Сначала cdв родительскую папку вашей коллекции MP3 (родительская папка artist1).

Теперь, если вы выполните следующую findкоманду, вы увидите такой вывод:

$ 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собирает все пути к файлам MP3, например, ./artist two/album one/Track1.mp3и передает их bashчерез-exec
  • $(echo "$1" | sed "s/\.\///" | tr " /" "-")используется для изменения имени выходного файла. sedудаляет первый символ ./и trпреобразует все пробелы и /в -.

Важно, чтобы вы запускали findс .помощью начального каталога, иначе (относительный) выходной путь не будет изменен правильно. Измените /tmp/music/на путь вашей музыкальной библиотеки.

Если вывод вас устраивает, удалите первый echoи выполните команду еще раз.

Выход:

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

Связанный контент