Массовое переименование, * nix версия

4569
Paolo B.

Я искал способ переименовать огромное количество файлов с одинаковыми именами, очень похоже на этот (вопрос, связанный с Windows), за исключением того, что я использую * nix (Ubuntu и FreeBSD, отдельно). Чтобы подвести итог, при использовании оболочки (Bash, CSH и т. Д.), Как мне массово переименовать несколько файлов, например, следующие файлы:

Бетховен - Мех Elise.mp3
Бетховен - Лунная соната.mp3
Бетховен - Ода радости.mp3
Бетховен - Ярость над потерянным Пенни.mp3

будут переименованы как эти?

Мех Elise.mp3
Лунная соната.mp3
Ода радости.mp3
Ярость над потерянным Пенни.mp3

Причина, по которой я хочу сделать это, состоит в том, что эта коллекция файлов будет находиться в каталоге с именем «Бетховен» (то есть префикс имени файла), и наличие этой информации в самом имени файла будет избыточным.

11

9 ответов на вопрос

12

Утилита переименования сделает то, что вы хотите.

Просто используйте rename 's/Beethoven\ -\ //g' *.mp3

Можете ли вы отредактировать, чтобы предоставить ссылку на утилиту, или она является стандартной в обоих упомянутых дистрибутивах (Ubuntu и FreeBSD)? Chris W. Rea 15 лет назад 0
Это идет с Perl. Debian использует ее в качестве команды переименования, поэтому я подозреваю, что Ubuntu тоже. Есть еще одна команда «переименовать», которая бесполезна, поэтому проверьте страницу руководства. derobert 15 лет назад 1
вау, синтаксис переименования очень похож на vim replace: D nXqd 13 лет назад 0
порт в / usr / ports / sysutils / rename отлично работал во FreeBSD Josh W. 12 лет назад 0
10
jtimberman

Подобно многим вещам в Linux / Unix, существует несколько способов сделать это!

Некоторые могут использовать mmv (масса mv).

Команда rename или prename, поставляемая с некоторыми пакетами Perl (более новыми Ubuntu и Debian), также может это делать.

prename 's/Beethoven\ -\ //g' Beethoven*.mp3 

Обратите внимание, что инструмент переименования в Fedora 10 не та же программа, что и эта, и работает по-другому. Он является частью другого пакета util-linux-ng и может быть найден здесь .

Я часто просто захожу в оболочку по привычке (ведь таких инструментов не всегда было).

mkdir -p Beethoven for x in Beethoven\ -\ * do mv "$x" Beethoven/"$" done 

Это создаст каталог Бетховена, затем переместит файл в этот каталог / имя файла, где имя файла заменено на «Бетховен -» ничем.

В качестве теста, прежде чем:

$ ls Beethoven - Fur Elise.mp3 Beethoven - Ode to Joy.mp3 Beethoven - Moonlight Sonata.mp3 Beethoven - Rage Over the Lost Penny.mp3 

После:

$ ls Beethoven/ Fur Elise.mp3 Ode to Joy.mp3 Moonlight Sonata.mp3 Rage Over the Lost Penny.mp3 
4
nagul

Попробуйте это решение, реализованное с использованием комбинации grep и rename. Это предполагает, что у вас есть целая куча каталогов, которые вам нужно переименовать. Если бы их было всего несколько, я бы использовал ручной подход, с шаблоном «Artist -», жестко закодированным для каждого.

# Rename any mp3 files in the directory hierarchy of type "a - b.mp3" to "b.mp3" find . -name "*.mp3" -exec rename -n -v 's|^(.*/).*-\s*(.*)\s*$|$1$2|g' {} \; 

Объяснение находки : находка команда находит все файлы с .mp3 расширением в текущей иерархии файлов и вызывает аргумент, переданный -exec для каждого. Обратите внимание, что в -exec, {} относится к аргументу, принятой находкой (путь файла + имя). В Гарантирует получает передаваемые переименовывать и вместо того, что указывает на конец находки команды.
\;;

Приведенная выше команда имеет ключ -n (без действия); следовательно, он скажет вам только то, что произойдет, если вы запустите его. Я рекомендую запускать эту команду без ключа -n только после того, как вы запустите ее один раз и будете удовлетворены предлагаемыми результатами.

Теперь для регулярного выражения.

  • ^ соответствует началу строки.
  • $ соответствует концу строки.
  • . соответствует любому персонажу.
  • *означает ноль или более предшествующей конструкции. Например, .*означает ноль или более символов.
  • \s обозначает любой космический символ.
  • \S обозначает любой не пробельный символ.
  • Все, что внутри ()получает захвачены и отражается как $1, $2в зависимости от его положения.

Регулярное выражение:

  • Ищет необязательную структуру каталогов в начале, фиксирует это в $ 1: (.*/)
  • Пропускает все до " -":.*-
  • Захватывает остальную часть строки, за исключением начальных и конечных пробелов, в $ 2: (.*)
  • Перезаписывает файл как $ 1 $ 2, который должен быть "/path/to/file/""filename.mp3"

Вот мой тестовый прогон:

/tmp/test$ ls -R .: a b c z-unknown.mp3  ./a: a3.mp3 a - longer title3.mp3 c.mp3 disc2 a - longer title2.mp3 a - long title.mp3 disc 1 the band - the title.mp3  ./a/disc 1: a - title1.mp3 a - title2.mp3  ./a/disc2: a - title1.mp3 a - title2.mp3  ./b: cd - ab - title3.mp3 cd - title1.mp3 cd - title2.mp3 c.mp3  ./c: c-pony2.mp4 c - pony3.mp3 c - pony4.mp3 c-pony.mp3  /tmp/test$ find . -name "*.mp3" -exec rename -v 's|^(.*/).*-\s*(.*)\s*$|$1$2|g' {} \; ./c/c-pony.mp3 renamed as ./c/pony.mp3 ./c/c - pony4.mp3 renamed as ./c/pony4.mp3 ./c/c - pony3.mp3 renamed as ./c/pony3.mp3 ./z-unknown.mp3 renamed as ./unknown.mp3 ./a/the band - the title.mp3 renamed as ./a/the title.mp3 ./a/a - longer title2.mp3 renamed as ./a/longer title2.mp3 ./a/a - longer title3.mp3 renamed as ./a/longer title3.mp3 ./a/disc 1/a - title1.mp3 renamed as ./a/disc 1/title1.mp3 ./a/disc 1/a - title2.mp3 renamed as ./a/disc 1/title2.mp3 ./a/a - long title.mp3 renamed as ./a/long title.mp3 ./a/disc2/a - title1.mp3 renamed as ./a/disc2/title1.mp3 ./a/disc2/a - title2.mp3 renamed as ./a/disc2/title2.mp3 ./b/cd - title1.mp3 renamed as ./b/title1.mp3 ./b/cd - title2.mp3 renamed as ./b/title2.mp3 ./b/cd - ab - title3.mp3 renamed as ./b/title3.mp3  /tmp/test$ ls -R .: a b c unknown.mp3  ./a: a3.mp3 c.mp3 disc 1 disc2 longer title2.mp3 longer title3.mp3 long title.mp3 the title.mp3  ./a/disc 1: title1.mp3 title2.mp3  ./a/disc2: title1.mp3 title2.mp3  ./b: c.mp3 title1.mp3 title2.mp3 title3.mp3  ./c: c-pony2.mp4 pony3.mp3 pony4.mp3 pony.mp3 

Regexp - дело непростое, и я написал немало ошибок, написав их, так что я бы приветствовал любой вклад в отсутствие этого достоинства. Я знаю, что нашел немало проверяющих это.

1
Zach Scrivena

Я собрал Java-программу командной строки, которая делает переименование файлов (и каталогов) быстрым, особенно для сценариев. Это бесплатно и с открытым исходным кодом, так что вы можете изменить его в соответствии с вашим сердцем:

RenameWand
http://renamewand.sourceforge.net/

Некоторые соответствующие примеры использования:

Переместите файлы формы "<a> - <b>"в соответствующий каталог "<a>":

java -jar RenameWand.jar "<a> - <b>" "<a>/<b>" 

Сортируйте файлы по времени последнего изменения и переименуйте их по 3-значному номеру:

java -jar RenameWand.jar "<a>" "<3|#FT> <a>" 

Переставьте части имени файла и измените регистр:

java -jar RenameWand.jar "<album> - <artist> - <song>.<ext>"  "<artist.upper> <album.title> - <song>.<ext.lower>" 
1
ocodo

zmv Инструмент переименования zsh очень хорош.

# zmv "programmable rename" # Replace spaces in filenames with a underline zmv '* *' '$f:gs/ /_' # Change the suffix from *.sh to *.pl zmv -W '*.sh' '*.pl' # lowercase/uppercase all files/directories $ zmv '(*)' '${(L)1}' # lowercase $ zmv '(*)' '${(U)1}' # uppercase 

Больше заметок здесь ...

0
TechScott

Для пингвинов это легко сделать с помощью сценария оболочки или сценария AWK. Для нас, простых смертных, вы можете попробовать Midnight Commander. Это в большинстве дистрибутивов Linux, из командной строки введите mc -a. Вы можете переименовывать файлы, используя регулярные выражения. Я использовал статью в GeekStuff http://www.thegeekstuff.com/2009/06/how-to-rename-files-in-group/, чтобы помочь мне.

0
Peter Eisentraut

Используйте vidir, а затем используйте функции редактора, чтобы применить шаблон переименования.

НАЗВАНИЕ

vidir - редактировать каталог

СИНТАКСИС

vidir [--verbose] [каталог | файл | -] ...

ОПИСАНИЕ

vidir позволяет редактировать содержимое каталога в текстовом редакторе. Если каталог не указан, текущий каталог редактируется.

При редактировании каталога каждый элемент в каталоге будет отображаться в своей пронумерованной строке. Эти цифры показывают, как vidir отслеживает, какие элементы изменены. Удалите строки, чтобы удалить файлы из каталога, или отредактируйте имена файлов, чтобы переименовать файлы. Вы также можете переключать пары чисел, чтобы поменять местами имена файлов.

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

ПРИМЕРЫ

vidir vidir * .jpeg Типичное использование.

найти | vidir - Редактировать содержимое подкаталога тоже. Чтобы удалить подкаталоги, удалите все их содержимое и сам подкаталог в редакторе.

найти -тип f | vidir - редактировать все файлы в текущем каталоге и подкаталогах.

АВТОР

Джои Хесс 2006-2010

Модификации Магнуса Волдриха 2011

АВТОРСКОЕ ПРАВО

Copyright 2006-2011 Vidir "АВТОР", как указано выше.

Лицензия под лицензией GNU GPL.

0
William Jockusch

Вот простой пример командной строки. У меня было слово «белый» в середине названия группы файлов PNG. Я хотел вынуть это и оставить только одно подчеркивание. Это сделало трюк:

for i in *.png; do mv "$i" "$"; done 
0
ocodo

На * NIX без Perl renameдоступны

В некоторых * nix переименование недоступно, поэтому необходимо выполнить переименование другим способом. Несколько лет назад я предложил zmvздесь, что, хотя и здорово, но не обязательно доступно.

Используя встроенные функции и sed, мы можем быстро создать сценарий оболочки, чтобы сделать это, что дает нам синтаксис, очень похожий на сценарий переименования perl, но при отсутствии некоторой изощренности в обработке ошибок он выполняет свою работу.

sedrename() { if [ $# -gt 1 ]; then sed_pattern=$1 shift for file in $(ls $@); do mv -v "$file" "$(sed $sed_pattern <<< $file)" done else echo "usage: $0 sed_pattern files..." fi } 

использование

sedrename 's/Beethoven\ -\ //g' *.mp3  before:  ./Beethoven - Fur Elise.mp3 ./Beethoven - Moonlight Sonata.mp3 ./Beethoven - Ode to Joy.mp3 ./Beethoven - Rage Over the Lost Penny.mp3  after:  ./Fur Elise.mp3 ./Moonlight Sonata.mp3 ./Ode to Joy.mp3 ./Rage Over the Lost Penny.mp3 

Скажем, мы тоже хотели создать целевые папки ...

Поскольку mvне создает папки, которые мы не можем использовать, sedrenameкак здесь, но это довольно небольшое изменение, поэтому я думаю, что было бы неплохо включить его тоже.

Нам нужна служебная функция abspath(или абсолютный путь), чтобы мы могли сгенерировать целевую папку (и) для шаблона sed / rename, который включает новую структуру папок.

abspath () { case "$1" in /*)printf "%s\n" "$1";; *)printf "%s\n" "$PWD/$1";; esac; } 

Это гарантирует, что мы знаем имена наших целевых папок. Когда мы переименуем, нам нужно использовать его в имени целевого файла.

# generate the rename target target="$(sed $sed_pattern <<< $file)"  # Use absolute path of the rename target to make target folder structure mkdir -p "$(dirname $(abspath $target))"  # finally move the file to the target name/folders mv -v "$file" "$target" 

Вот полный сценарий с поддержкой папок ...

sedrename() { if [ $# -gt 1 ]; then sed_pattern=$1 shift for file in $(ls $@); do target="$(sed $sed_pattern <<< $file)" mkdir -p "$(dirname $(abspath $target))" mv -v "$file" "$target" done else echo "usage: $0 sed_pattern files..." fi } 

Конечно, это все еще работает, когда у нас нет определенных целевых папок.

Если мы хотим поместить все песни в папку, ./Beethoven/мы можем сделать это:

использование

sedrename 's|Beethoven - |Beethoven/|g' *.mp3  before:  ./Beethoven - Fur Elise.mp3 ./Beethoven - Moonlight Sonata.mp3 ./Beethoven - Ode to Joy.mp3 ./Beethoven - Rage Over the Lost Penny.mp3  after:  ./Beethoven/Fur Elise.mp3 ./Beethoven/Moonlight Sonata.mp3 ./Beethoven/Ode to Joy.mp3 ./Beethoven/Rage Over the Lost Penny.mp3 

Бонус раунд ...

Используя этот скрипт для перемещения файлов из папок в одну папку:

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

sedrename 's|.*/||' **/*.mp3  before:  ./Beethoven/Fur Elise.mp3 ./Beethoven/Moonlight Sonata.mp3 ./Beethoven/Ode to Joy.mp3 ./Beethoven/Rage Over the Lost Penny.mp3  after:  ./Beethoven/ # (now empty) ./Fur Elise.mp3 ./Moonlight Sonata.mp3 ./Ode to Joy.mp3 ./Rage Over the Lost Penny.mp3 

Обратите внимание на шаблоны регулярных выражений

В этом сценарии применяются правила регулярных шаблонов sed, эти шаблоны не являются PCRE (регулярные выражения, совместимые с Perl). Вы могли бы использовать расширенный синтаксис регулярного выражения, используя один sed -rили в sed -E зависимости от вашей платформы.

См. POSIX-совместимое man re_formatдля полного описания основных и расширенных шаблонов регулярных выражений.

Похожие вопросы