2013-10-24 121 views
0

我确信这已被回答之前,但我似乎无法使用正确的搜索条件来找到它。Bash匹配文件名中的模式,然后添加/编辑

我想写一个bash脚本,可以识别,排序和重命名基于他们的名字中的模式的文件。

拿这个文件名,例如:BBC东西的东西3 5的胡说2007.avi

我想剧本认识到,由于文件名与BBC开始,包含匹配模式“位上的东西DIGIT“,脚本应该通过在前面删除BBC重新命名它,在3前面插入字符串”s01e0“,并删除”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 

然后什么也没有。我想要一些帮助!谢谢!

回答

0

使用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/' 

我们使用捕获组到ma文件名的TCH有趣的部分:

  • BBC - 匹配字面BBC,
  • \(.*\) - 匹配的一切,并记住它捕获组1日起至
  • \([0-9]\) - 一个数字,记住它的捕获组2,然后
  • of [0-9] - 匹配 “的” 和数字文字,
  • \(.*\) - 比赛休息并记住它捕获组3

,然后把他们的位置,我们希望:

  • \1 - 捕获组1,即内容一切 “BBC” 和第一个数字间
  • s01e0 - 字面 “s01e0”
  • \2 - 捕获组2,即集数
  • \3的内容 - 捕获组3,即一切内容

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

+0

非常感谢!这真是太好了,我非常感谢随之而来的解释。你是我的英雄。 – Artfail