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

Как я могу пакетно переименовать с помощью терминала набор файлов, в которых несколько номера имеют один и тот же префикс, так что все эти префиксы устанавливаются на новые?

Например:

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 ]

Очень признателен за вашу помощь в выяснении этого вопроса, Спасибо!

2
задан 16 June 2021 в 15:40

3 ответа

Используя 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
' *
2
ответ дан 28 July 2021 в 11:28

В bash

Попробуйте это (сухой запуск) из каталога, содержащего файлы:

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

1
ответ дан 28 July 2021 в 11:28

Если вы хотите, чтобы файлы с одним и тем же исходным префиксом сопоставлялись с тем же префиксом в новой схеме , не полагаясь на вычитание, то вы можете сделать это, создав хэш (ассоциативный массив) префиксов, нумерация их последовательно, а затем выполнение замен переименования путем поиска в хэше. Бывший.

$ 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 в конце сопоставления и соответственно выбрать ширину вывода.

2
ответ дан 28 July 2021 в 11:28

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

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