因此,我有以下 shell 脚本,用于批量重命名某些给定电视剧的剧集:
#!/bin/bash
#script for renaming files of form "*01*.ext" to "Episode 01.ext";
counter=0
for all_files in * ; do
counter=$(( $counter+1 )) #increments $counter by 1;
#creates counter "number" with two digit format (eg: 01):
if [[ 1 = $(( $counter<10 )) ]] ; then
number=0$counter
else
number=$counter
fi
#checks all file names for presence of $number and renames those files:
for numbered_file in *$number* ; do
ext=${numbered_file##*.}
mv "$numbered_file" "Episode $number.$ext"
done
done
我现在想改进脚本以解决一些非常常见的异常。特别是,我不希望“720p”中的“20”被解释为指“第 20 集”。那么我想要的是一种*$number*
从内部 for 循环细化模式的方法。 (是分配给、等的变量number
。 )01
02
03
我如何实现以下目标:
*
这里没有“7”这里$number
没有“0”或“p”*
请随意指出上述脚本中任何其他做得很笨拙的地方。这是我第一次尝试一个模糊有用的脚本,因此它可能充满了风格上的怪物。 ;-)
答案1
看起来你正在重新发明现有的工具,例如mmv
-rename
有几个程序被称为,rename
但我正在考虑的一个是 perl 重命名又名prename
(它包含perl
在 debian 和衍生版本中的包中,也可能包含在其他发行版中)。
我会提供一些它们的用法示例,但您没有给我们源文件名的示例(请参阅上面的评论)。
顺便说一句,由于您的脚本是 bash 而不是 sh,您可以将 if/then/else 替换为 bash 内置的零填充 $number,printf
如下所示:
printf -v number "%02d" "$counter"
在 POSIX shell 中,您可以number=$(printf "%02d" $counter)
改为使用。该printf
命令是 GNU Coreutils 的一部分。
答案2
Bash 有一个正则表达式匹配结构:
[[ $string =~ regexp ]]
不过,这对你想做的事情没有太大帮助。要从文件名中提取有趣的数字,请去掉无聊的部分并保留最后的非无聊数字序列。
shopt -s extglob
number=$filename
number=${number//[0-9][0-9]+([0-9])p}
number=${number%%+([^0-9])}
number=${number##*[^0-9]}