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


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

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

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

Мех Elise.mp3
Лунная соната.mp3
Ode to Joy.mp3
Rage Over the Lost Penny.mp3

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


11
2017-08-19 06:57


происхождения




ответы:


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

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


12
2017-08-19 07:35



Можете ли вы отредактировать, чтобы предоставить ссылку на утилиту, или она стандартная в обоих упомянутых дистрибутивах (Ubuntu и FreeBSD)? - Chris W. Rea
Он поставляется с Perl. Debian использует его как команду переименования, поэтому я подозреваю, что Ubuntu тоже делает это. Существует еще одна команда «rename», которая бесполезна, поэтому проверьте man-страницу. - derobert
wow, синтаксис переименования выглядит очень похоже на замену vim: D - nXqd
порт в / usr / ports / sysutils / rename отлично работал в FreeBSD - Josh W.


Как и многие другие вещи с 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

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

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

$ 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

10
2017-08-19 07:10





Попробуйте это решение, реализованное с использованием комбинации grep и переименования. Это предполагает, что у вас есть целая группа каталогов, которые вам нужно переименовать. Если их всего несколько, я бы пошел с ручным подходом, с шаблоном «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 - сложный бизнес, и я сделал много ошибок, написав их, поэтому я бы приветствовал любой вклад в отсутствие заслуг этого. Я знаю, что нашел немало тестов.


4
2017-08-19 09:18





Я собрал программу 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
2017-08-21 20:44





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

Больше примечаний здесь ...


1
2018-01-12 00:10





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


0
2017-08-19 07:36





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

for i in *.png; do mv "$i" "${i/white/}"; done

0
2018-06-01 00:26





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

ИМЯ

vidir - изменить каталог

СИНТАКСИС

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

ОПИСАНИЕ

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

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

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

ПРИМЕРЫ

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

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

find -type f | видир -          Отредактируйте все файлы под текущим каталогом и подкаталогами.

АВТОР

Джои Хесс 2006-2010

Модификации Magnus Woldrich 2011

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

Copyright 2006-2011 vidir "AUTHOR", как указано выше.

Лицензируется в соответствии с GNU GPL.


0
2017-09-03 12:39





На * 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

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

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


0
2018-03-11 01:37