У меня есть группа файлов, которые имеют следующие имена:
048. banana.mkv
049. apple.mkv
050. mango.mkv
051. pear.mkv
052. grape.mkv
Мне нужно переименовать эти файлы в следующем соглашении об именах
01. banana.mkv
02. apple.mkv
03. mango.mkv
04. pear.mkv
05. grape.mkv
Проблема в том, что у меня есть сотни файлов, которые мне нужно переименовать, и несколько групп, которые нужно начинать с 01
и увеличивать. Обычно я использую rename
для массового переименования файлов. В этой ситуации я использовал qvm
для изменения каждого имени файла. Конечно, есть более простой способ.
Использование утилиты переименования на основе perl
:
$ rename -n 's/^(\d+)/sprintf "%02d", $1-47/e' *.mkv
rename(048. banana.mkv, 01. banana.mkv)
rename(049. apple.mkv, 02. apple.mkv)
rename(050. mango.mkv, 03. mango.mkv)
rename(051. pear.mkv, 04. pear.mkv)
rename(052. grape.mkv, 05. grape.mkv)
Прикол в этом e
модификатор при замене s / pattern / replace /
- который позволяет e оценивать строку замены как выражение perl - включая арифметику $ 1-47
и дополненное форматирование через sprintf
. Удалите -n
, когда вы убедитесь, что он делает все правильно.
Если у вас есть только оболочка, то:
$ for f in *.mkv; do
n="${f%%.*}"
printf -v newf '%02d.%s' "$((10#$n-47))" "${f#*.}"
echo mv -- "$f" "$newf"
done
mv -- 048. banana.mkv 01. banana.mkv
mv -- 049. apple.mkv 02. apple.mkv
mv -- 050. mango.mkv 03. mango.mkv
mv -- 051. pear.mkv 04. pear.mkv
mv -- 052. grape.mkv 05. grape.mkv
Удалите эхо
, как только вы будете счастливы. что он делает правильно.
С помощью zsh
и zmv
% autoload zmv
% setopt expanded_glob
%
% zmv -n '(*[0-9])(*.mkv)' '${(l:2::0:)$(( $1-47 ))}$2'
mv -- '048. banana.mkv' '01. banana.mkv'
mv -- '049. apple.mkv' '02. apple.mkv'
mv -- '050. mango.mkv' '03. mango.mkv'
mv -- '051. pear.mkv' '04. pear.mkv'
mv -- '052. grape.mkv' '05. grape.mkv'
В этом случае форматирование числа выполняется с использованием модификатора расширения l
(letter ell) - из man zshexpn
:
l: expr :: string1 :: string2: Дополните получившиеся слова слева. Каждое слово будет указывается при необходимости и помещается в поле expr символов шириной.
Как и в случае , переименуйте
, удалите -n
, чтобы фактически изменить имена.
Я предполагаю, что начальный номер не всегда должен быть 048
, и в этом случае вам может понадобиться команда, которую вы можете запустить - без изменения - в каждом каталоге и всегда выполняет команду Правильно.
Вы можете запустить это в каждом каталоге:
file-rename -n 's/^\d{3}\./sprintf "%02d.", ++our $i/e' -- *.mkv
Это похоже на ответ SteelDriver , главное отличие в том, что он выясняет, с чего начать. Есть и другие незначительные отличия. Обратите внимание, что , если есть пробелы во входной нумерации, это заполнит те пробелы в выходной нумерации, которые могут или не могут быть тем, что вы хотите. То есть, если ваши файлы были 048. banana.mkv
, 049. apple.mkv
и 051. mango.mkv
, результат будет 01. banana.mkv
, 02. apple.mkv
и 03. mango.mkv
( не 04. mango.mkv
).
Как написано, эта команда не переименовывает какие-либо файлы из-за -n
вариант. Вместо этого он показывает, что он будет делать . Если вас это устраивает, вы можете запустить его снова без -n
:
file-rename 's/^\d{3}\./sprintf "%02d.", ++our $i/e' -- *.mkv
У вас может не быть команды file-rename
. Если вы этого не сделаете, то, скорее всего, у вас нет команды rename
или (и именно поэтому я рекомендую использовать file-rename
вместо rename
) вашего Команда rename
может быть чем-то совершенно другим. Если ты не Если у вас нет file-rename
(или, если вы предпочитаете записать его как , переименуйте
и не имеете его), вы можете получить его, установив пакет rename
. :
sudo apt update && sudo apt install rename
Когда ваша оболочка расширяет шаблон глобуса, например *. Mkv
, в список имен файлов, результирующий список имеет лексикографический порядок . Что именно это означает, зависит от вашей текущей локали, и в целом это не то же самое, что числовой порядок, даже если они применимы. Однако, поскольку ваши имена файлов нумеруются в самом начале и все числа дополняются слева до 0
с, эта проблема не возникает, и ваша оболочка расширяется *. Mkv
в численно упорядоченный список путей.
Поскольку оболочка заботится об этом, Остальная мера предосторожности заключается в том, чтобы переименовать файл
избегать изменения любых файлов, которые не начинаются с последовательности из трех цифр, за которой следует .
.
В выражении подстановки s / ^ \ d {3} \ ./ sprintf "% 02d.", ++ our $ i / e
:
^ \ d {3} \.
это регулярное выражение. Соответствует литералу .
( \.
), встречающийся сразу после трех ( {3}
) цифр ( \ d
) в начале имени файла ( ^
).
sprintf "% 02d.", ++ наш $ i
- это код Perl.
Он использует глобальную переменную $ i
, представляя ее как таковую, если она еще не видна ( наш
). $ i
начинается со значения ноль, но увеличивается при каждом его использовании, непосредственно перед его использованием (префикс ++
делает это). Таким образом, он принимает значения 1, 2, 3 и т. Д. Для каждого файла.
sprintf
используется для его форматирования, если необходимо, дополненного слева нулями, до ширины 2, после чего следует буквальный .
. (.
необходимо экранировать только в регулярном выражении, в противном случае он будет соответствовать любому символу, а не в выражении для подстановки.
e
в конце приводит к тому, что выражение будет ] вычислялся как Perl-код для получения результата подстановки. Без этого e
фактический текст, начинающийся с sprintf
, будет подставляться в каждое имя файла, а не в результат оценки этот текст в виде кода Perl.
Файлы, имена которых не начинаются с трех цифр, за которыми следует .
не переименовываются и не приводят к увеличению $ i
. Имена файлов, которые не заканчиваются суффиксом .mkv
, даже не передаются в file-rename
.
Вы можете просто захотеть выполните это один раз для каждого каталога, так как похоже, что у вас есть только несколько каталогов. Но если вы хотите автоматизировать это, вы можете. Это можно сделать с помощью find
, хотя это сложнее и сложнее, чем может показаться на первый взгляд, из-за того, как выглядят пути из find
(например, с -execdir
вы получите такие пути, как ./ 048. Banana.mkv
), и потому что -exec
/ -execdir
с +
будет разбиваться на несколько команд (сброс $ i
нежелательно) в случае очень большой каталоги (которых у вас нет, но это еще один фактор, который необходимо учитывать).
Так что вы можете просто захотеть использовать цикл оболочки для его запуска:
for d in dir1 dir2; do
printf '%s:\n' "$d"
(cd -- "$d" && file-rename -n 's/^\d{3}\./sprintf "%02d.", ++our $i/e' -- *.mkv)
done
(Это также не будет работать для каталогов с огромное количество файлов *. mkv
, но это даст сообщения об ошибках для этих каталогов, вместо того, чтобы делать неправильные действия.)
Замените dir1 dir2
вашим фактическим списком каталогов, содержащим файлы, которые вы хотите переименовать.
Это приводит к выводу типа:
dir1:
rename(048. banana.mkv, 01. banana.mkv)
rename(049. apple.mkv, 02. apple.mkv)
rename(050. mango.mkv, 03. mango.mkv)
rename(051. pear.mkv, 04. pear.mkv)
rename(052. grape.mkv, 05. grape.mkv)
dir2:
rename(099. foo.mkv, 01. foo.mkv)
rename(100. bar.mkv, 02. bar.mkv)
rename(101. baz.mkv, 03. baz.mkv)
Если это выглядит хорошо, вы можете удалить -n
, как и раньше. (Вы по-прежнему будете видеть заголовки каталогов, но не строки rename (..., ...)
. Если вы хотите увидеть их тоже во время фактического переименования, вы можете передать опцию -v
в file-rename
, т.е. заменить -n
на -v
вместо простого удаления -n
. Однако это может затруднить обнаружение любых сообщений об ошибках.)
Массовое переименование файлов в Ubuntu; В кратком введении к команде переименования (автор Оли ) показаны и объяснены несколько способов использования переименования
, в том числе с sprintf
.
применяется как к текущему Perl renamer file-rename
, так и к старому prename
. (В последних выпусках Ubuntu file-rename
и prename
одинаковы, но в более старых выпусках они отличались и имели несколько другое поведение.) В Ubuntu rename
по умолчанию либо отсутствует, либо является символической ссылкой, которая разрешает одну из них. Это не относится к rename.ul
, другой утилите, которая в некоторых системах - и в Ubuntu, если вы ее настраиваете - запускается при запуске rename
.
Для получения информации о регулярных выражениях в Perl я рекомендую perldoc perlrequick
и perldoc perlre
. Они охватывают синтаксис выражений s /
.
Для получения информации о регулярных выражениях в целом я рекомендую https://www.regular-expressions.info .