当我试图修复电视剧的集数时,我尝试使用重命名函数并尝试将 printf 的返回值作为重命名参数传递,但无法做到。我尝试了几乎所有的组合
for j in $(seq 1 9);
do
rename 's/"$( - "`printf "%d" ${j}`" - )"/"$( - "`printf "0%d" ${j}`" - )"/g' *
done
我能想到但似乎没有任何作用。我最终只是手动完成,因为在这种情况下我只关心 1-9,所以
rename 's/- 1 -/- 01 -/g' *
rename 's/- 2 -/- 02 -/g' *
...
有人可以指出为什么上述内容不起作用以供将来参考吗?
答案1
你用单引号引用整个表达式,所以不会发生 shell 插值,Perl 会看到"$( - "
printf "%d" ${j}最奇怪的正则表达式" - )"
,它被 Perl 插值成类似的内容
% perl -E 'say qq{"$( - "`printf "%d" ${j}`" - )"}'
"42 640 - "`printf "%d" `" - )"
%
因为您要求 Perl 插入$(
变量,您可以通过 阅读该变量perldoc -v '$('
。可以说,这个正则表达式可能与您的文件不匹配。 (并演示了尝试将多种语言嵌入到一个极其复杂的字符串中的几个陷阱之一;实际上没有必要,因为 Perl 可以完成这一切。)
更好的方法是匹配和调整您感兴趣的内容,这里似乎是用连字符括起来的数字;假设文件名中只有一个数字,只需匹配保存反向引用([0-9]+)
并使用Perlsprintf
函数适当地填充这些数字(加上重要的/e
标志,将右侧视为表达式,以便sprintf
实际被调用)。
% touch "blah - "{1..9}" - blah"
% ls
blah - 1 - blah blah - 3 - blah blah - 5 - blah blah - 7 - blah blah - 9 - blah
blah - 2 - blah blah - 4 - blah blah - 6 - blah blah - 8 - blah
% rename 's/([0-9]+)/sprintf "%02d", $1/e' *
% ls
blah - 01 - blah blah - 04 - blah blah - 07 - blah
blah - 02 - blah blah - 05 - blah blah - 08 - blah
blah - 03 - blah blah - 06 - blah blah - 09 - blah
%
如果文件名中的其他地方有数字,则使用正则表达式来说明这一点,也许类似于
% rename 's/- ([0-9]+) -/sprintf "- %d -", $1/e' *
% ls
blah - 1 - blah blah - 3 - blah blah - 5 - blah blah - 7 - blah blah - 9 - blah
blah - 2 - blah blah - 4 - blah blah - 6 - blah blah - 8 - blah
%
要rename
最有效地使用正则表达式,请参阅