Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash匹配文件名中的模式,然后添加/编辑_Bash_Pattern Matching_Filenames_Glob - Fatal编程技术网

Bash匹配文件名中的模式,然后添加/编辑

Bash匹配文件名中的模式,然后添加/编辑,bash,pattern-matching,filenames,glob,Bash,Pattern Matching,Filenames,Glob,我相信这个问题以前已经得到了回答,但我似乎无法使用正确的搜索词来查找它 我正在尝试编写一个bash脚本,它可以根据文件名中的模式识别、排序和重命名文件 以这个文件名为例:BBC Something 3/5 Blah 2007.avi 我想让脚本认识到,由于文件名以BBC开头,并且包含与“DIGIT of DIGIT”模式匹配的内容,脚本应该通过删除前面的BBC、在3前面插入字符串“s01e0”以及删除“of 5”来重命名它把它变成某种东西s01e03等等2007。avi 此外,我希望脚本能够识别

我相信这个问题以前已经得到了回答,但我似乎无法使用正确的搜索词来查找它

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

以这个文件名为例:BBC Something 3/5 Blah 2007.avi

我想让脚本认识到,由于文件名以BBC开头,并且包含与“DIGIT of DIGIT”模式匹配的内容,脚本应该通过删除前面的BBC、在3前面插入字符串“s01e0”以及删除“of 5”来重命名它把它变成某种东西s01e03等等2007。avi

此外,我希望脚本能够识别并以不同的方式处理名为bbcsother2009.mkv的文件。在这种情况下,我需要脚本认识到,由于文件名以BBC开头,以一年结束,但不包含“数字中的数字”模式,它应该通过在BBC之后插入单词“documentaries”来重命名它,然后在之后的一年复制和粘贴,因此,文件名将变为“BBC纪录片2009其他内容”。mkv

我希望这不需要太多的帮助。。。我自己一整天都在做这件事,但这就是我的全部:

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

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

使用
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 3 of 5 Blah 2007.avi->Something s01e03 Blah 2007.avi
BBC Something 2009.mkv->BBC纪录片2009 Something other.mkv
不是来自BBC.mkv的东西->
让我们看看其中一个
sed
调用:

sed -e 's/BBC\(.*\)\([0-9]\) of [0-9]\(.*\)/\1 s01e0\2 \3/'
我们使用捕获组来匹配文件名的有趣部分:

  • BBC
    -匹配文字BBC
  • \(.*)
    -匹配所有内容并在捕获组1中记住,直到
  • \([0-9]\)
    -一个数字,在捕获组2中记住它,然后
  • [0-9]的-匹配文字“of”和数字
  • \(.*)
    -匹配其余部分并在捕获组3中记住它
然后把他们放在我们想要的位置:

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

这可能会导致许多多余的空格,因此最后会有另一个
sed
调用来清理这些空格。

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