Заполнение ВТОРОЕ ВРЕМЯ чисел в сотнях файлов - PullRequest
0 голосов
/ 29 января 2019

У меня есть сотни файлов с именами по следующей схеме:

XX - YY Title.ext

Однако они не всегда сортируются должным образом, поскольку XX и YY могут быть1 или 2 цифры.Я хотел бы переименовать файлы так, чтобы XX и YY всегда были двумя цифрами, добавив, если необходимо, начальный ноль.

Например, в настоящее время я получаю сортировку, которая выглядит следующим образом:

1 - 1 BillyBob.ext   
1 - 10 Jimmy2.ext  
1 - 2 Stewy3.ext  
10 - 1 Cletus.ext     
2 - 1 Homer.ext

То, что я хочу, это:

01 - 01 BillyBob.ext
01 - 02 Stewy3.ext
01 - 10 Jimmy2.ext
02 - 01 Homer.ext
10 - 01 Cletus.ext

Я успешно изменил XX часть, используя код:

rename -n 's/\d+/sprintf("%02d", $&)/e' *

Однако я не могу понять, как свойствовыполнить что-то, что будет действовать в части YY.

**** Прикреплено к сообщению оригинала ****

В частности, я не знаю, как действовать в части YY безтакже действует на любые числовые символы, которые появляются позже в имени файла.

**** Конец добавленного содержимого ****

Любая помощь приветствуется.

Спасибо!

Ответы [ 3 ]

0 голосов
/ 29 января 2019

Для полноты: это также может быть решено непосредственно в оболочке (UNIX) с помощью sort из GNU coreutils:

$ cat dummy.txt
1 - 1 BillyBob.ext
1 - 10 Jimmy.ext
1 - 2 Stewy.ext
10 - 1 Cletus.ext
2 - 1 Homer.ext

$ sort --field-separator=- -k 1n -k 2n <dummy.txt
1 - 1 BillyBob.ext
1 - 2 Stewy.ext
1 - 10 Jimmy.ext
2 - 1 Homer.ext
10 - 1 Cletus.ext

т.е.

  • используйте -в качестве разделителя полей,
  • сортировка по первому полю численно, и
  • сортировка по второму полю численно
0 голосов
/ 29 января 2019

Попробуйте этот Perl однострочный

perl -lne ' s/(\d+)\s-\s(\d+)\s+(\S+)/sprintf("%02d-%02d %s",$1,$2,$3)/ge; $kv{$_}=1 ; END { print join("\n",sort keys %kv) } '

со входами

$ cat notorious.txt
1 - 1 BillyBob.ext
1 - 10 Jimmy.ext
1 - 2 Stewy.ext
10 - 1 Cletus.ext
2 - 1 Homer.ext

$ perl -lne ' s/(\d+)\s-\s(\d+)\s+(\S+)/sprintf("%02d-%02d %s",$1,$2,$3)/ge; $kv{$_}=1 ; END { print join("\n",sort keys %kv) } ' notorious.txt
01-01 BillyBob.ext
01-02 Stewy.ext
01-10 Jimmy.ext
02-01 Homer.ext
10-01 Cletus.ext

$
0 голосов
/ 29 января 2019

Вам не хватает /g в вашем операторе замещения.Без него Perl просто изменяет первое совпадение с регулярным выражением в строке.

#!/usr/bin/perl

use strict;
use warnings;

while (<DATA>) {
  s/\d+/sprintf('%02d', $&)/eg;
  print;
}

__DATA__
1 - 1 BillyBob.ext
1 - 10 Jimmy.ext
1 - 2 Stewy.ext
10 - 1 Cletus.ext
2 - 1 Homer.ext

Вывод:

01 - 01 BillyBob.ext
01 - 10 Jimmy.ext
01 - 02 Stewy.ext
10 - 01 Cletus.ext
02 - 01 Homer.ext

Обновление: Чтобы справиться с новым требованием,Вы добавили в свой вопрос, нам нужно сделать регулярное выражение более явным.В этом исправлении я ищу два набора цифр, разделенных тире.Я фиксирую два набора цифр (которые помещают их в $1 и $2) и раскрываю их в правой части оператора подстановки.

Единственная строка, которую мне нужно было изменить, - это строка, содержащаязамена.Теперь это выглядит так:

s/(\d+) - (\d+)/sprintf('%02d - %02d', $1, $2)/e;

(И, поскольку здесь мы делаем только одну замену, мы можем потерять опцию /g.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...