Мне нужно переименовать кучу музыкальных файлов из Artist - Title [FREE DL].mp3 и Artist - Title [FREE DL] [PREMIERE].mp3 чтобы просто Artist - Title.mp3

У меня есть это, но это не работает, и я не могу сказать, почему.

find . -type f -name "* - * \[*\].mp3" -o -name "* - * \[*\] \[*\].mp3" -execdir bash -c 'for file in "$@"; do new=${file% \[}.mp3; mv -v "$file" "$new"; done' _ {} +

Из-за того, что я не волшебник bash, я не могу заставить его исправить. Я знаю, что поиск находит файлы, но переименование ничего не делает, и попытка oto echo $new ничего не делает.

1 ответ1

0

Несколько вещей не так:-

  • Причина ничего не выходит, потому что -o больше ничего не делать , если предыдущее выражение совпадает - это включает в себя и пытается соответствовать второй -name и выполнение последующего -execdir но первое выражение совпадает для обоих стилей имени файла, поэтому больше ничего не делается. Если вам нужно сопоставить две разные маски файлов, используйте скобки \( -name ... -o -name ... \) , но в этом случае лучше всего просто удалить предложение -o и второе -name .
  • После выполнения -execdir с расширением имени файла происходит две ошибки:
    • ${file% \[} удаляет все завершающие пробелы и открытые квадратные скобки из имени файла - их нет (все имена файлов заканчиваются на p3);
    • вам нужно ${file% \[*} чтобы включить остальную часть имени файла, но это все еще недостаточно, потому что один % соответствует самой короткой из возможных строк, то есть только от последней пустой и открытой квадратной скобки - до совпадение с первого, вам нужно ${file%% \[*} , что соответствует самой длинной строке.

Итак, что вам нужно, это:

find . -type f \( -name "* - * \[*\].mp3" -o -name "* - * \[*\] \[*\].mp3" \) -execdir bash -c 'for file in "$@"; do new=${file%% \[*}.mp3; mv -v "$file" "$new"; done' _ {} +

или, проще:

find . -type f -name "* - * \[*\].mp3" -execdir bash -c 'for file in "$@"; do new=${file%% \[*}.mp3; mv -v "$file" "$new"; done' _ {} +

Я проверил их, насколько смог, с помощью тестовых файлов и ввода echo перед командой mv , и теперь они, похоже, работают.

Тем не менее, кажется немного странным использовать опцию '+' для создания строки имен файлов, а затем использовать for их повторной изоляции, так что я бы наконец предложил:

find . -type f -name "* - * \[*\].mp3" -execdir bash -c 'file="{}"; echo mv -v "$file" "${file%% \[*}.mp3"' \;

Я удалил new переменную, так как ее значение может быть одинаково хорошо расширено в строке.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .