Как переименовать несколько файлов, заменив слово в имени файла?

36

Заменить ACDC на AC-DC

Например, у нас есть эти файлы

ACDC - Рок-н-ролл не шумовое загрязнение .xxx

ACDC - Rocker.xxx

ACDC - Shoot To Thrill.xxx

Я хочу, чтобы они стали:

AC-DC - Рок-н-ролл не шумовое загрязнение .xxx

AC-DC - Rocker.xxx

AC-DC - стрелять в трепет.xxx

Я знаю, что sed или awk используется для этой операции. Я не могу ничего гуглить, поэтому я прошу вашей помощи =) Не могли бы вы предоставить полную рабочую команду оболочки для этой задачи?

Обратная связь: Решение для пользователей OSX

Holms
источник
1
Я чувствую, что здесь есть более крупный вопрос - вы пытаетесь исправить имена файлов mp3 в целом? Есть много сценариев, которые люди написали за эти годы, чтобы сделать это. Я думаю, что тот, кого я использовал, был назван mp3fixer.
Фил Холленбек
нет, дело не в mp3, мне просто нужно управлять огромными файлами с похожими именами, и что-то, что все должно быть заменено или исправлено ... обычная ситуация, поэтому мне нужно это изящное решение для переименования всех из них
holms

Ответы:

45
rename 's/ACDC/AC-DC/' *.xxx

от man rename

DESCRIPTION
       "rename" renames the filenames supplied according to the rule specified as the 
first argument.  The perlexpr argument is a Perl expression which is expected to modify the 
$_ string in Perl for at least some of the filenames specified.  If a given filename is not 
modified by the expression, it will not be renamed.  If no filenames are given on
           the command line, filenames will be read via standard input.

Например, чтобы переименовать все файлы, соответствующие «* .bak», чтобы удалить расширение, вы можете сказать,

rename 's/\.bak$//' *.bak

Чтобы перевести прописные имена в нижние, вы должны использовать

rename 'y/A-Z/a-z/' *
Джоэл К
источник
5
Обратите внимание, что многие машины linux поставляются с переименованием из util-linux, который реализует простую замену, а не регулярные выражения. Так что, если переименовать ничего не получится, ничего не делая, вы, вероятно, используете неправильно rename.
Фил Холленбек
Я искал это целую вечность! Thnx!
Холмс
@PhilHollenback Как найти / установить правильный тогда? :)
Генри
Это не работает, когда у меня есть подчеркивания в именах файлов вместо пробелов - как я могу решить это?
Нед
13

Этот ответ содержит хорошие части из всех других ответов, исключая такую ​​ересь как ls | while read.

Текущий каталог:

for file in ACDC*.xxx; do
    mv "$file" "${file//ACDC/AC-DC}"
done

Включая подкаталоги:

find . -type f -name "ACDC*" -print0 | while read -r -d '' file; do
    mv "$file" "${file//ACDC/AC-DC}"
done

Символы новой строки действительно маловероятны в именах файлов, поэтому это может быть проще при работе с именами, содержащими пробелы:

find . -type f -name "ACDC*" | while read -r file; do
    mv "$file" "${file//ACDC/AC-DC}"
done
grawity
источник
9

Чтобы использовать версию util-linux, на renameкоторую ссылался Фил (в Ubuntu она называется rename.ul):

rename ACDC AC-DC ACDC*

или

rename.ul ACDC AC-DC ACDC*
Приостановлено до дальнейшего уведомления.
источник
1
ваш вариант самый лучший =) так много глупых статей в гугле о find, send и awk ... к этой простой операции, для которой уже переименована egxist!
Холмс
4

Использование оболочки bash

find . -type f -name "ACDC*" -print0 | while read -d $'\0' f
do
   new=`echo "$f" | sed -e "s/ACDC/AC-DC/"`
   mv "$f" "$new"
done

Примечание: использование findбудет обрабатывать текущий каталог и каталоги в.

Кольцо Ø
источник
1

Зависит от вашей оболочки. В Zsh я бы сделал это:

for file in ACDC*.xxx; do
    mv "$file" "$(echo $file | sed -e 's/ACDC/AC-DC/')"
done

Вероятно, не лучшее решение, но работает.

Полемон
источник
1

Используя bash:

ls *.xxx | while read fn; do
    mv "${fn}" "${fn/ACDC/AC-DC}";
done

Если у вас установлена renameпрограмма:

rename 's/ACDC/AC-DC/' *.xxx
ThatGraemeGuy
источник