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

11

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

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

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

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

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

Паоло Б.
источник

Ответы:

12

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

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


источник
Можете ли вы отредактировать, чтобы предоставить ссылку на утилиту, или она является стандартной в обоих упомянутых дистрибутивах (Ubuntu и FreeBSD)?
Крис В. Ри
1
Это идет с Perl. Debian использует ее в качестве команды переименования, поэтому я подозреваю, что Ubuntu тоже. Есть еще одна команда «переименовать», которая бесполезна, поэтому проверьте страницу руководства.
Дероберт
вау, синтаксис переименования очень похож на vim replace: D
Dzung Nguyen
порт в / usr / ports / sysutils / rename отлично работал во FreeBSD
Джош В.
10

Подобно многим вещам в 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/"${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
jtimberman
источник
4

Попробуйте это решение, реализованное с использованием комбинации 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' {} \;

Объяснение find :
Команда find находит все файлы с расширением .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

Я собрал 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

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

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

ocodo
источник
0

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

TechScott
источник
0

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

for i in *.png; do mv "$i" "${i/white/}"; done
Уильям Джокуш
источник
0

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

ИМЯ

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

СИНТАКСИС

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

ОПИСАНИЕ

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

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

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

ПРИМЕРЫ

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

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

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

АВТОР

Джои Хесс 2006-2010

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

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

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

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

Питер Айзентраут
источник
0

На * 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для полного описания основных и расширенных шаблонов регулярных выражений.

ocodo
источник