Как я могу пакетно переименовать с помощью терминала набор файлов, в которых несколько номера имеют один и тот же префикс, так что все эти префиксы устанавливаются на новые?
Например:
011.foo.txt -> 001.foo.txt
011.bar.psd -> 001.bar.psd
011.baz.gif -> 001.baz.gif
012.qux.js -> 002.qux.js
012.corge.png -> 002.corge.png
...
020.thud.txt -> 010.thud.txt
Я бы хотел использовать команду переименования, если возможно:
rename [ -h|-m|-V ] [ -v ] [ -0 ] [ -n ] [ -f ] [ -d ] [ -e|-E perlexpr]*|perlexpr [ files ]
Очень признателен за вашу помощь в выяснении этого вопроса, Спасибо!
Используя perl переименуйте
по запросу.
В отношении того, что демонстрирует ваш вопрос:
rename -n 's/^(\d+)/sprintf "%03d", $1-10/e' *
результат пробного прогона:
rename(011.bar.psd, 001.bar.psd)
rename(011.baz.gif, 001.baz.gif)
rename(011.foo.txt, 001.foo.txt)
rename(012.corge.png, 002.corge.png)
rename(012.qux.js, 002.qux.js)
rename(020.thud.txt, 010.thud.txt)
Для того, что говорится в заголовке вопроса, с фактическими последовательными префиксами:
rename -n -E 'use vars q{$n}' -e 's/^(\d+)/sprintf "%03d", ++$n/e' *
rename(011.bar.psd, 001.bar.psd)
rename(011.baz.gif, 002.baz.gif)
rename(011.foo.txt, 003.foo.txt)
rename(012.corge.png, 004.corge.png)
rename(012.qux.js, 005.qux.js)
rename(020.thud.txt, 006.thud.txt)
Для первого, если вы не хотите жестко кодировать дельту 10
:
rename -n -E 'use vars q{$delta}' -e '
s{^(\d+)}{
$delta = $1 - 1 unless defined $delta;
sprintf "%03d", $1 - $delta
}e
' *
Попробуйте это (сухой запуск) из каталога, содержащего файлы:
for f in *
do
r="${f#*.}"
p="${f%%.*}"
if [ "$p" -eq "$p" ] 2>/dev/null
then
p="$((10#$p - 10))"
p="$(printf "%03d" $p)"
echo mv -- "$f" "$p.$r"
fi
done
Если вас устраивает печатный вывод, то измените строку:
echo mv -- "$f" "$p.$r"
на:
mv -- "$f" "$p.$r"
удалив echo
, чтобы выполнить фактическое переименование.
Если вы хотите, чтобы файлы с одним и тем же исходным префиксом сопоставлялись с тем же префиксом в новой схеме , не полагаясь на вычитание, то вы можете сделать это, создав хэш (ассоциативный массив) префиксов, нумерация их последовательно, а затем выполнение замен переименования путем поиска в хэше. Бывший.
$ rename -n -E '
BEGIN {
my $n = 1;
our %pfxs;
foreach my $f (@ARGV) {
$pfxs{$1} = (exists $pfxs{$1} ? $pfxs{$1} : $n++) if $f =~ /^(\d{3})/
}
}
our %pfxs;
s/^(\d{3})/sprintf "%03d", $pfxs{$1}/e
' [0-9][0-9][0-9].*
rename(011.bar.psd, 001.bar.psd)
rename(011.baz.gif, 001.baz.gif)
rename(011.foo.txt, 001.foo.txt)
rename(012.corge.png, 002.corge.png)
rename(012.qux.js, 002.qux.js)
rename(020.thud.txt, 003.thud.txt)
Поскольку он не полагается на вычитание, этот метод можно использовать, даже если исходные префиксы не являются числовыми.
Это, несомненно, можно улучшить - в частности, можно проверить максимальное значение $ n
в конце сопоставления и соответственно выбрать ширину вывода.