如何将捕获的regex组传递给perl-rename中的shell命令



我有一组文件,我想使用WSL Ubuntu中提供的重命名实用程序批量重命名。我的文件名包含以下模式,我想更正文件中的日期格式。

file_10Feb2022.pptx
file_10Mar2022.pptx
file_17Feb2022.pptx
file_17Mar2022.pptx
file_24Feb2022.pptx
file_3Feb2022.pptx
file_3Mar2022.pptx

我尝试使用以下命令重命名

rename -n "s/_(.*)./_`date +%F -d 1`./g" *.pptx

我用正则表达式捕获日期部分,并试图使用日期命令(在"中(正确格式化,但无法将捕获的正则表达式组(\1(传递给shell命令。

使用rename -n标志运行它会返回以下输出,其中它将尝试重命名为当前日期(2022-08-03(,而不是指定的日期。

rename(file_10Feb2022.pptx, file_2022-08-03.pptx)
rename(file_10Mar2022.pptx, file_2022-08-03.pptx)
rename(file_17Feb2022.pptx, file_2022-08-03.pptx)
rename(file_17Mar2022.pptx, file_2022-08-03.pptx)
rename(file_24Feb2022.pptx, file_2022-08-03.pptx)
rename(file_3Feb2022.pptx, file_2022-08-03.pptx)
rename(file_3Mar2022.pptx, file_2022-08-03.pptx)

我有另一个文件夹,里面装满了带有不同日期格式后缀的文件,我想捕获它,让日期命令处理格式,而不是捕获日期、月份和年份等单独的部分。有什么关于如何正确执行的想法吗?

这可能超出了一行是个好主意的范围,但是:

$ rename 's{_(.*?)(.[^.]+)$}{
my ($d,$s) = ($1,$2);
my $nd = `date +%F -d "$d"`;
chomp $nd;
$? ? $& : "_$nd$s" 
}e' file_*
  • s{}{}e-搜索和替换,将替换视为代码
  • backticks中的代码是shell命令(带插值(
  • 如果设置了$?,则返回原始值;否则更换
  • date错误将像往常一样出现在stderr上;不会重命名受影响的文件
  • chomp删除从backticks中接收到的换行符,否则它将最终出现在文件名中
  • ?:是三元算子:if ? then : else
  • 某些输入在传递到shell时可能是不安全的,应该转义@ikegami指出,外壳是完全可以避免的。例如,类似以下内容:
use IPC::System::Simple qw( capturex );
my $nd = capturex( "date", "+%F", "-d", $d );

您的命令返回当前日期的原因:

rename -n "s/_(.*)./_`date +%F -d 1`./g" *.pptx

因为使用了双引号,所以backtick是由shell扩展的,而不是通过重命名扩展的(但重命名需要/e,不要将backtick语句作为插入的文本。

最新更新