Несколько вещей не так:-
- Причина ничего не выходит, потому что
-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
переменную, так как ее значение может быть одинаково хорошо расширено в строке.