Perl重命名实用程序在日常文件工作中表现非常出色,特别是在我不时检查我的MP3集合时.
有些人有一种可怕的习惯,就是总是将艺术家的名字大写,就像这样
03 - ARTIST NAME - Song Title.mp3
我希望将其重命名为一个更加平静的混合案例,就像这样
03 - Artist Name - Song Title.mp3
但是,它也应该以智能的方式完成.
可能有法语或意大利语标题,如:
05 - JEAN BAGUETTE - Honi soit qui mal y pense.mp3
要么
07 - SIGNORE AL FORNO - Pazzi sono tutti i calciatori.mp3
因此,我不希望这些变成混合的情况 – 只有艺术家的一部分.
一种没有用的方法是
rename 's/(\d{1,2} - )([A-Z ]+)([\s\S]+)/$1lc($2)$3/' filename
无论如何我都会发布它,因为它总能让你更好地了解我正在尝试做什么.
我也尝试用一个临时变量替换$2(因为我不允许更改$2,因为它是只读的)并在打印出结果之前执行lc(),但是我没有成功.但无论如何,我是一个Perl初学者.
解决方法
我知道这样做的最清楚的方法是进行两阶段评估(使用/ e修饰符)替换.
在下面的代码中,外部替换选择艺术家名称,包括其边界连字符并替换它.
内部的一个取1美元 – 艺术家的名字 – 并用非空格字符的每个子序列替换首先用lc低位的相同字符串然后用ucfirst大写.
目前,该程序将打印前后名称.从重命名行中删除#以进行重命名.
use strict; use warnings; my @data = ( '05 - JEAN BAGUETTE - Honi soit qui mal y pense.mp3','07 - SIGNORE AL FORNO - Pazzi sono tutti i calciatori.mp3',); for my $file (@data) { (my $new = $file) =~ s{(-[^-]+-)}{ (my $artist = $1) =~ s/(\S+)/ucfirst lc $1/eg; $artist; }e; print "$file\n"; print "$new\n"; print "\n"; # rename $file,$new; }
产量
05 - JEAN BAGUETTE - Honi soit qui mal y pense.mp3 05 - Jean Baguette - Honi soit qui mal y pense.mp3 07 - SIGNORE AL FORNO - Pazzi sono tutti i calciatori.mp3 07 - Signore Al Forno - Pazzi sono tutti i calciatori.mp3
更新
您可能喜欢的另一种方法是在连字符上拆分文件名,编辑第二部分并将它们连接在一起.
从上面的主循环变为
for my $file (@data) { my @file = split /-/,$file; $file[1] =~ s/(\S+)/ucfirst lc $1/eg; my $new = join '-',@file; print "$file\n"; print "$new\n"; print "\n"; # rename $file,$new; }
更新2
I just experimented with using /-.*?-/ then using substr($_,$-[0],
$+[0]) as an lvalue for =~ s/// but sadly it didn’t work
这似乎是一个很好的想法,我不得不尝试它.
你对substr的调用是错误的,因为$ – [0]和$[0]是字符串的偏移量. substr的第三个参数必须是字符串长度,所以你需要写substr($_,$ – [0],$[0] – $ – [0])
此代码工作正常,并再次产生与以前相同的结果
for my $file (@data) { next unless $file =~ /-[^-]+-/; my $new = $file; substr($new,$+[0]-$-[0]) =~ s/(\S+)/ucfirst lc $1/eg; print "$file\n"; print "$new\n"; print "\n"; # rename $file,$new; }