shell 脚本的模式匹配异常

shell 脚本的模式匹配异常

因此,我有以下 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。 )010203

我如何实现以下目标:

*这里没有“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]}

相关内容