Как я могу легко массово переименовывать файлы с помощью Perl?
Вопрос
У меня есть много файлов, которые я пытаюсь переименовать, я попытался создать регулярное выражение, чтобы соответствовать им, но даже при этом я застрял на файлах с именами типа:
Имя файла 01
Имя файла 100
Имя файла 02
Имя файла 03
и т.д., я хотел бы добавить "0" (ноль) за любым файлом, размер которого меньше 100, вот так:
Имя файла 001
Имя файла 100
Имя файла 002
Имя файла 003
Самое близкое, что я смог сделать, чтобы сопоставить их, было использование этого find -type d | sort -r | grep ' [1-9] [0-9] $' однако я не мог понять, как их заменить.Заранее благодарю за любую помощь, которую вы можете мне предложить.Я на CentOS, если это может как-то помочь, все это делается через SSH.
Решение
perl -e 'foreach $f (glob("File\\ Name*")) { $nf = $f; $nf =~ s/(\d+)$/sprintf("%03d",$1)/e; print `mv \"$f\" \"$nf\"`;}'
Может быть, это немного перебор, но он делает то, о чем просят.
Другие советы
find . -type d -print0 | xargs -0 rename 's/(\d+)/sprintf "%03d", $1/e'
или что-то в этом роде, при условии
- У вас есть GNU find и GNU xargs (для
-print0
и-0
) - У вас есть утилита "переименовать", которая поставляется вместе с perl
- В имени файла есть только одна группа цифр.Если их больше одного, то вам нужно что-то сделать с регулярным выражением, чтобы оно соответствовало только тому номеру, который вы хотите переформатировать.
Это что, одноразовая вещь?Если это так, я собираюсь предложить кое-что, что многим программистам здесь может показаться отговоркой:
Передайте вывод вашей команды по каналу (find -type d | sort -r | grep ' [1-9][0-9]$'
) в файл и используйте редактор вместе с некоторой глобальной магией поиска / замены, чтобы создать скрипт, который выполняет переименования.
Затем выбросьте сценарий.
Здесь мало суеты и мало шансов, что вы в конечном итоге прострелите себе ногу, предприняв какую-нибудь попытку создать умный (но неадекватно отлаженный) однострочник, который уйдет в сорняки в ваших файлах.
Выполните две команды в таком порядке:
$ rename 's/File Name (\d)$/File Name 0$1/' *
$ rename 's/File Name (\d\d)$/File Name 0$1/' *
Первый переименовывает все, что меньше 10, и добавляет ноль.Второй переименовывает все, что меньше 100, и добавляет ноль.Результат должен состоять из трех цифр для всех имен файлов.
В моем debian это хорошо работает с переименованием, протестировано с 300 файлами.
perl -e 'map `touch door$_.txt`, 1..300;'
rename 's/(\d+)\.txt/sprintf("%03d.txt", $1)/e' *.txt
Я думаю , что mmv здесь твой друг.
вы могли бы что-то сделать, используя perl или ruby.
поместите все эти файлы в один каталог
dirlisting = DIR.entries('.')
dirListing.each do |file|
num = file.match(/\d+$/).to_i
if num < 100
find the position where start the number, with index and inject the 0 there.
end
end
use strict;
use File::Copy;
my @files = glob 'File*Name*';
foreach my $filename (@files) {
if ($filename =~ m`^.*File.*Name.*?(\d+)`) {
my $number = $1;
next if ($number > 99);
rename $filename, sprintf("FileName%03d",$number);
}
}
если ваш пульт дистанционного управления имеет оболочку bash
for i in File*;
do
case "${i##* }" in [0-9][0-9] )
echo mv "$i" "${i% *} $(printf "%03d" ${i##* })" ;;
esac;
done
удалите "echo", чтобы выполнить фактическое переименование