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

utugiqy6  于 2022-11-15  发布在  Perl
关注(0)|答案(1)|浏览(129)

我有一组文件,我想使用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
我用regex捕获了date部分,并试图使用date命令(在''内)正确格式化,但我无法将捕获的regex组(\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)

我有另一个文件夹充满了具有不同的日期格式的后缀的文件,我想捕获它,让日期命令处理格式,而不是我捕获像日期,月份和年份这样的个别部分。关于如何正确执行这一点有什么想法?

q5lcpyga

q5lcpyga1#

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

$ rename 's{_(.*?)(\.[^.]+)$}{
    my ($d,$s) = ($1,$2);
    my $nd = `date +%F -d "$d"`;
    chomp $nd;
    $? ? $& : "_$nd$s" 
}e' file_*
  • s{}{}e-搜索和替换,将替换视为代码
  • 反勾号中的代码是shell命令(带插值)
  • 如果$?置位出错,则返回原值;否则进行替换
  • date错误将照常出现在stderr上;不会重命名受影响的文件
  • chomp删除从反勾号接收到的换行符,否则它将在文件名中结束
  • ?:是三进制运算符:if ? then : else
  • 某些输入在传递到shell时可能是不安全的,应该进行转义;@ikegami注意到shell可以完全避免。例如,类似于:
use IPC::System::Simple qw( capturex );
my $nd = capturex( "date", "+%F", "-d", $d );

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

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

因为您使用了双引号,所以反勾号是由shell展开的,而不是由rename展开的(但是rename需要/e,而不是将反勾号语句作为要插入的文字文本。

相关问题