Как переименовать файлы из одного возрастающего шаблона в другой?

У меня есть группа файлов, которые имеют следующие имена:

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 для изменения каждого имени файла. Конечно, есть более простой способ.

3
задан 9 June 2020 в 21:42

2 ответа

Использование утилиты переименования на основе 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 , чтобы фактически изменить имена.

3
ответ дан 19 June 2020 в 21:27

Я предполагаю, что начальный номер не всегда должен быть 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 .

2
ответ дан 19 June 2020 в 21:27

Другие вопросы по тегам:

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