Bash匹配文件名中的模式,然后添加/编辑(Bash to match pattern in filename then add/edit)

编程入门 行业动态 更新时间:2024-10-25 08:22:19
Bash匹配文件名中的模式,然后添加/编辑(Bash to match pattern in filename then add/edit)

我确信之前已经回答过,但我似乎无法使用正确的搜索词找到它。

我正在尝试编写一个bash脚本,它可以根据名称中的模式识别,排序和重命名文件。

拿这个文件名,例如: BBC Something Something 3 of 5 Blah 2007.avi

我希望脚本能够识别出由于文件名以BBC开头并且包含与“DIGIT of DIGIT”相匹配的内容,脚本应该通过删除前面的BBC来重命名它,在前面插入字符串“s01e0” 3,删除“5”,将其变成Something Something s01e03 Blah 2007.avi

另外,我希望脚本能够识别和处理一个名为的文件,例如BBC Something Else 2009.mkv 。 在这种情况下,我需要脚本识别,因为文件名以BBC开头并以一年结束,但不包含 “DIGIT of DIGIT”模式,它应该通过在BBC之后插入“纪录片”一词重新命名,然后复制并粘贴一年后的那一年,以便文件名将成为BBC纪录片2009 Something Else.mkv

我希望这不是要求太多帮助......我一整天都在努力做这件事,但这实际上就是我所拥有的:

topic1 () { if [ "$2" = "bbc*[:digit:] of [:digit:]" ]; then

然后什么都没有。 我会喜欢一些帮助! 谢谢!

I'm sure this has been answered before, but I can't seem to use the right search terms to find it.

I'm trying to write a bash script that can recognize, sort, and rename files based on patterns in their names.

Take this filename, for example: BBC Something Something 3 of 5 Blah 2007.avi

I would like the script to recognize that since the filename starts with BBC and contains something that matches the pattern "DIGIT of DIGIT," the script should rename it by removing the BBC at the front, inserting the string "s01e0" in front of the 3, and removing the "of 5," turning it into Something Something s01e03 Blah 2007.avi

In addition, I'd like for the script to recognize and deal differently with a file named, for example, BBC Something Else 2009.mkv . In this case, I need the script to recognize that since the filename starts with BBC and ends with a year, but does not contain that "DIGIT of DIGIT" pattern, it should rename it by inserting the word "documentaries" after BBC and then copying and pasting the year after that, so that the filename would become BBC documentaries 2009 Something Else.mkv

I hope this isn't asking for too much help... I've been working on this myself all day, but this is literally all I've got:

topic1 () { if [ "$2" = "bbc*[:digit:] of [:digit:]" ]; then

And then nothing. I'd love some help! Thanks!

最满意答案

使用grep匹配需要更改的文件名,然后sed实际更改它们:

#!/bin/bash get_name() { local FILENAME="${1}" local NEWNAME="" # check if input matches our criteria MATCH_EPISODE=$(echo "${FILENAME}" | grep -c "BBC.*[0-9] of [0-9]") MATCH_DOCUMENTARY=$(echo "${FILENAME}" | grep -c "BBC.*[0-9]\{4\}") # if it matches then modify if [ "${MATCH_EPISODE}" = "1" ]; then NEWNAME=$(echo "${FILENAME}" | sed -e 's/BBC\(.*\)\([0-9]\) of [0-9]\(.*\)/\1 s01e0\2 \3/') elif [ "${MATCH_DOCUMENTARY}" = "1" ]; then NEWNAME=$(echo "${FILENAME}" | sed -e 's/BBC\(.*\)\([0-9]\{4\}\)\(.*\)/BBC documentaries \2 \1 \3/') fi # clean up: remove trailing spaces, double spaces, spaces before dot echo "${NEWNAME}" | sed -e 's/^ *//' -e 's/ / /g' -e 's/ \./\./g' } FN1="BBC Something Something 3 of 5 Blah 2007.avi" FN2="BBC Something Else 2009.mkv" FN3="Something Not From BBC.mkv" NN1=$(get_name "${FN1}") NN2=$(get_name "${FN2}") NN3=$(get_name "${FN3}") echo "${FN1} -> ${NN1}" echo "${FN2} -> ${NN2}" echo "${FN3} -> ${NN3}"

输出是:

BBC Something Something 3 of 5 Blah 2007.avi -> Something Something s01e03 Blah 2007.avi
BBC Something Else 2009.mkv -> BBC documentaries 2009 Something Else.mkv
Something Not From BBC.mkv -> 
 

让我们看一下sed调用:

sed -e 's/BBC\(.*\)\([0-9]\) of [0-9]\(.*\)/\1 s01e0\2 \3/'

我们使用捕获组来匹配文件名的有趣部分:

BBC - 与文字BBC相匹配, \(.*\) - 匹配所有内容并在捕获组1中记住它,直到 \([0-9]\) - 一个数字,记住它在捕获组2中,然后 of [0-9] - 匹配文字“of”和数字, \(.*\) - 匹配休息并在捕获组3中记住它

然后把它们放在我们想要的位置:

\1 - 捕获组1的内容,即“BBC”和第一个数字之间的所有内容 s01e0 - 文字“s01e0” \2 - 捕获组2的内容,即剧集编号 \3 - 捕获组3的内容,即其他所有内容

这可能会导致许多多余的空间,所以最后还有另一个sed调用来清理它。

Use grep to match filenames that need to be changed and then sed to actually change them:

#!/bin/bash get_name() { local FILENAME="${1}" local NEWNAME="" # check if input matches our criteria MATCH_EPISODE=$(echo "${FILENAME}" | grep -c "BBC.*[0-9] of [0-9]") MATCH_DOCUMENTARY=$(echo "${FILENAME}" | grep -c "BBC.*[0-9]\{4\}") # if it matches then modify if [ "${MATCH_EPISODE}" = "1" ]; then NEWNAME=$(echo "${FILENAME}" | sed -e 's/BBC\(.*\)\([0-9]\) of [0-9]\(.*\)/\1 s01e0\2 \3/') elif [ "${MATCH_DOCUMENTARY}" = "1" ]; then NEWNAME=$(echo "${FILENAME}" | sed -e 's/BBC\(.*\)\([0-9]\{4\}\)\(.*\)/BBC documentaries \2 \1 \3/') fi # clean up: remove trailing spaces, double spaces, spaces before dot echo "${NEWNAME}" | sed -e 's/^ *//' -e 's/ / /g' -e 's/ \./\./g' } FN1="BBC Something Something 3 of 5 Blah 2007.avi" FN2="BBC Something Else 2009.mkv" FN3="Something Not From BBC.mkv" NN1=$(get_name "${FN1}") NN2=$(get_name "${FN2}") NN3=$(get_name "${FN3}") echo "${FN1} -> ${NN1}" echo "${FN2} -> ${NN2}" echo "${FN3} -> ${NN3}"

The output is:

BBC Something Something 3 of 5 Blah 2007.avi -> Something Something s01e03 Blah 2007.avi
BBC Something Else 2009.mkv -> BBC documentaries 2009 Something Else.mkv
Something Not From BBC.mkv -> 
 

Let's see at one of sed invocations:

sed -e 's/BBC\(.*\)\([0-9]\) of [0-9]\(.*\)/\1 s01e0\2 \3/'

We use capture groups to match interesting portions of the filename:

BBC - match literal BBC, \(.*\) - match everything and remember it in capture group 1, until \([0-9]\) - a digit, remember it in capture group 2, then of [0-9] - match literal " of " and digit, \(.*\) - match rest and remember it in capture group 3

and then put them in positions we want:

\1 - content of capture group 1, i.e. everything between "BBC" and first digit s01e0 - literal " s01e0" \2 - content of capture group 2, i.e. episode number \3 - content of capture group 3, i.e. everything else

This may result in many superfluous spaces so at the end there is another sed invocation to clean that up.

更多推荐

本文发布于:2023-07-15 21:59:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1119346.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:文件名   编辑   模式   Bash   match

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!