2

我有一组 vhs 传输的电视剧集,所有这些剧集的标题都按照“显示名称 SXXEYY 剧集 Title.mp4”的格式命名,我想给它们添加 iTunes mp4 标签。我有一种从命令行执行此标记的方法,但想改进我的 shell 脚本功能并编写一些可以自动执行此操作的东西。

我认为 bash 脚本会为我做这件事。理想情况下,正确编写的正则表达式会查看文件名并返回 Show、Season、Episode 和 Title,并允许我将这些结果传递给 bash 脚本中的标记工具。正确编写的正则表达式将返回 BASH_REMATCH[1]..[4] 有了这四个数据。

这就是我被卡住的地方 - 我似乎无法让我的正则表达式序列表现出来。

我对语法的理解向我暗示了以下表达式:

Regex for Show Name: ^(?:(?! S[0-9][0-9]).)*
Regex for Season Number: (?<=S)(.*)(?=E)
Regex for Episode Number: (?<=S[0-9][0-9]E)..
Regex for Episode Title: (?<=S[0-9][0-9]E[0-9][0-9] )(.*)(?=.(mp4))

应该会产生可接受的结果。但到目前为止,我什至无法让 bash 返回任何参数。我显然错过了一些东西,但是

#!/bin.bash

for filename in "Cop Rock S01E03 Happy Mudder's Day.mp4" ; do
    if [[ "$filename" =~ (?<=S[0-9][0-9]E[0-9][0-9] )(.*)(?=.(mp4)) ]]; then
        echo  "${BASH_REMATCH[1]}${BASH_REMATCH[2]}"
    fi
done

应该返回一个剧集名称和 mp4 后缀,但到目前为止结果还没有出来。

我也对其他解决方案持开放态度,例如使用 sed,但我以前从未使用过 sed,几乎无法拼写,因此学习曲线可能很陡峭。

如果有人能指出我所犯的错误,我将不胜感激。这是 bash 3.2;=~ 运算符确实有效。

4

2 回答 2

5

bash您正在尝试使用不理解的 Perl 样式的正则表达式(特别是零宽度后向断言) 。尝试以下操作:

regex="(.*) S([0-9]{2})E([0-9]{2}) (.*)\.mp4"
for filename in "Cop Rock S01E03 Happy Mudder's Day.mp4" ; do
    if [[ "$filename" =~ $regex ]]; then
        echo "Show: ${BASH_REMATCH[1]}"
        echo "Season: ${BASH_REMATCH[2]}"
        echo "Episode: ${BASH_REMATCH[3]}"
        echo "Title: ${BASH_REMATCH[4]}"
    fi
done
于 2013-06-12T20:07:28.590 回答
0

我知道距离上一次关于这个问题的活动已经 1.5 年了,但我一直在寻找同样的东西并找到了这个答案。我将答案调整为更通用(允许所有小写文件名、点而不是空格、不同的扩展名和多个文件名),所以我想与您分享我的更新:

#!/bin/bash

regex="(.*)[ .][sS]([0-9]{2})[eE]([0-9]{2})[ .](.*)\.(mp4|mkv)"
for filename in ${*}
do
    if [[ "${filename}" =~ ${regex} ]]; then
        echo "Show: ${BASH_REMATCH[1]}"
        echo "Season: ${BASH_REMATCH[2]}"
        echo "Episode: ${BASH_REMATCH[3]}"
        echo "Title: ${BASH_REMATCH[4]}"
    fi
done

如果将其复制到 shell 文件中并使其可执行,则可以更通用地使用它。

于 2014-12-20T09:54:56.440 回答