在数百个文件中填充数字的第二次出现

时间:2019-01-29 11:21:18

标签: regex perl

我有数百个文件使用以下方案命名:

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 :(得分:4)

您在替换运算符上缺少/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选项。)

答案 1 :(得分:2)

出于完整性考虑,也可以使用GNU coreutils中的sort在(UNIX)Shell上直接解决此问题:

$ 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

  • 使用-作为字段分隔符,
  • 按第一字段的数字排序,然后
  • 按第二个字段数字排序

答案 2 :(得分:0)

尝试使用此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

$