2012-11-06 34 views
4

请耐心等待的时候,这个帖子会有些长......更换和添加​​前导零重命名文件

我有一大堆的文件,其中一些用一个简单的和干净的名称(例如1E01.txt)有些还有很多额外功能:

Sample2_Name_E01_-co_032.txt 
Sample2_Name_E02_-co_035.txt 
... 
Sample12_Name_E01_-co_061.txt 

等等。这里重要的是“样品”后面的数字和“名称”之后的字母+数字 - 其余部分是一次性的。如果我摆脱非重要的部分,文件名减少到与“干净”文件名(2E01.txt,2E02.txt,...,12E01.txt)相同的模式。我已经成功地将文件与下面的表达式重命名(想出了这个一个自己,不知道是不是很优雅,但工作正常):

rename -v 's/Sample([0-9]+)_Name_([A-Z][0-9]+).*/$1$2\.txt/' *.txt 

现在,第二部分则加入了领先只有一位数的文件名为零,例如1E01.txt变为01E01.txt。我已经成功地将它与(发现修改此另一个StackExchange后):

rename -v 'unless (/^[0-9]{2}.*\.txt/) {s/^([0-9]{1}.*\.txt)$/0$1/;s/0*([0-9]{2}\..*)/$1/}' *.txt 

所以,我终于得到了我的问题:有没有办法在短短的一个重命名命令合并这两个表达式?我知道我可以做一个bash脚本来实现这个过程的自动化,但是我想要的是找到一个通过重命名的解决方案。

感谢

+0

我不明白为什么你会想要一个通过解决方案的两个本质上不同的操作。如果你愿意,你可以把两个命令放在同一行。 – Tim

+0

只是寻找优雅。它们并不是不同的操作,都是重命名相同的文件。 –

+0

@Tim N:Afterthought:你说得对,因为我有两种类型的名字,我想我需要两种表情。 –

回答

10

你可以试试这个命令重命名1-file.txt0001-file.txt

# fill zeros 
$ rename 's/\d+/sprintf("%04d",$&)/e' *.txt 

您可以更改命令一点,以满足您的需要。

1

那么如果这是你的“解析”正则表达式,那么你就限制了脚本可以对那些匹配那些模式的文件起作用的文件。因此,使用相同的文字字符串的sprintf不是更专业的情况下,你可能只是这样做:

s{Sample(\d+)_Name_(\p{IsUpper})(\d+)} 
{sprintf "Sample%02d_Name_%s%03d", $1, $2, $3}e 
; 

在这里,你再次使用相同的已知的功能和简单的格式化附带的数字。

  • /e switch适用于'eval',它将评估替换为每个匹配的Perl。
  • 我改名一些你的表情更标准的字符类符号:[A-Z]成为属性类\p{IsUpper}[0-9]成为数字代码\d(也可能\p{IsDigit})。