Массовое переименование каталогов для перемещения года от конца к началу

11

В настоящее время я борюсь с некоторыми музыкальными папками. Однажды я решил назвать их по образцу: artist - album - year. Сегодня я понял, что это был неумный шаг, и теперь хочу назвать мои каталоги в соответствии с шаблоном: так year - artist - albumкак они будут отображаться в порядке возрастания в списке.

Я начал делать переименование вручную, но с примерно 700 папками должен быть более простой способ; Я пытался использовать, gprenameно я не очень хорош в регулярных выражений и сценариев Bash ...

Есть ли кто-нибудь, кто мог бы помочь мне избавить мои бедные кончики пальцев?

Несколько примеров:

Aes Dana - Memory Shell - 2004 
Anja Schneider & GummiHz - Back To Back (Remixes Part 2) - 2009

станет

2004 - Aes Dana - Memory Shell
2009 - Anja Schneider & GummiHz - Back To Back (Remixes Part 2)

РЕДАКТИРОВАТЬ: некоторые имена исполнителей и альбомов имеют специальные символы, такие как And.Idили Kool & The Gang. Хотя в каждом каталоге есть -разделитель.

TazMayhem
источник
2
Пожалуйста, добавьте несколько примеров имен каталогов и ожидаемый результат.
Муру
Например: у меня есть «Aes Dana - Memory Shell - 2004», и я хотел бы иметь «2004 - Aes Dana - Memory Shell»
TazMayhem
1
Вы знаете, как редактировать вопрос, так почему бы вам не добавить это к вопросу? Кроме того, есть ли какие-нибудь из названий альбомов или исполнителей -?
Муру
Упорядочено ли имя по разделителю «-» по определению, и возможно ли оно встречается в другом месте имени?
Джейкоб Влейм
Я склонен перенаправлять исходные папки в текстовый файл, а затем использовать vim. Я создаю макрос, чтобы создать второй параметр для каждой строки с соответствующими компонентами исходной папки в правильном порядке, а затем использую другой макрос, чтобы поставить mv в начале каждой строки. Я мог бы даже пойти так далеко, чтобы сначала взять копию структуры папок на случай, если я запутался в / потерянных папках.

Ответы:

16

Предполагая, что у вас есть доступ к Perl rename(обычно доступен в Ubuntu - спасибо @Serg за разъяснение различий. Если вы сомневаетесь, позвоните, /usr/bin/renameи вы должны получить правильный), вы можете использовать:

rename -n 's/(.*) - (\d{4})\//$2 - $1/' */

Удалить -nпосле тестирования, чтобы фактически переименовать каталоги. Это предполагает дату всех альбомов между 1000 и 9999. Вероятно, разумно ...

объяснение

  • s/old/newзаменить oldнаnew
  • (.*)сохранить любое количество любых символов для ссылки, как $1позже
  • (\d{4})\/сохранить четыре цифры в конце строки для ссылки, как $2позже.
  • */ сопоставлять все каталоги (не файлы - спасибо @muru за помощь!)
Занна
источник
3
Может быть, сделать, */чтобы соответствовать только каталоги.
Муру
@ Муру, похоже, не работает! Что я тупо делаю?
Занна
1
@ Занна, я думаю, то, что они имеют в виду, это то, что у некоторых оболочек mkshесть встроенная функция rename. Достаточно заменить его на полный путь или позвонить, prenameчтобы вызвать переименование Perl
Сергей Колодяжный
1
@Zanna Обнаружил этот интересный фрагмент : unix.stackexchange.com/a/229248/85039 TL; DR : rename«иногда не называют prename», но, очевидно, это две «ветви» одного и того же сценария, который не поддерживается Debian и другой, которая есть. Так что да . , , это много беспорядка - у некоторых оболочек есть свои rename, у пакета perl свой rename, а у самого debian есть отдельный пакет
Сергей Колодяжный,
1
@Zanna Я думал о программе, упомянутой rename.ulв unix.stackexchange.com/q/229230/21167
zwol
6

Простой скрипт Python может сделать такую ​​работу:

$ tree
.
├── Aes Dana - Memory Shell - 2004
├── Anja Schneider & GummiHz - Back To Back (Remixes Part 2) - 2009
└── rename_dirs.py

2 directories, 1 file
$ ./rename_dirs.py */
$ tree
.
├── 2004 - Aes Dana  -  Memory Shell 
├── 2009 - Anja Schneider & GummiHz  -  Back To Back (Remixes Part 2) 
└── rename_dirs.py

Содержание скрипта:

#!/usr/bin/env python
from shutil import move;
import sys

for i in sys.argv[1:] :
    parts = i[:-1].split('-')
    year = parts[-1].strip()
    new_name = year + " - " + " - ".join(parts[:-1]).strip()
    move(i,new_name)

Как это работает:

  • Основной трюк в том, что мы выполняем скрипт из той же директории, где находятся цели. Мы также передаем */в качестве аргументов скрипту только каталоги
  • Скрипт перебирает все аргументы командной строки, разбивая каждое имя файла на список строк по -символу. Новое имя файла состоит из частей, которые мы извлекли.
  • move()Функция из shutilsмодуля - это то, что на самом деле переименовывает каталоги

Обратите внимание на использование: ./rename_dirs.py */

Сергей Колодяжный
источник