从文件名中提取信息以进行自动复制

时间:2014-01-07 15:53:06

标签: regex linux bash sed

这是我在StackOverflow上的第一篇文章。要温柔。 :)

我有一个Linux服务器,我下载电视节目并手动将文件移动到各自的文件夹,供我的Plex服务器使用。我想自动化这个过程。我已经到了下面。

文件命名约定Show.Name.SeasonNumberEpisodeNumber.HDTV.X264.etc ...

  

示例:Almost.Human.S01E01.720p.HDTV.X264.mkv

注意:显示名称可以是不同的长度。在名称中的每个单词之间。

我可以从文件名中提取show文件夹名称。

#!/bin/bash
readonly FILEPATH=~/downloads
readonly SAVEPATH=~/shows

for file in $FILEPATH/*.mkv
do
#Get foldername from filename (everything before .S0 is foldername
        foldername=$(basename "${file%.S0*}" | tr '.' ' ')
#Need to convert extracted season info into folder name ex. S01 = Season 1
#       seasonfolder=$(basename "${file}" | sed -e 's/^[^S0]*//;')

#Copy the file to the path we built.
#Auto-create folder if it doesn't exist?

#       cp $file  "$SAVEPATH/$foldername/#seasonfolder"

done

问题:

  • 我还想从文件名中提取季节信息 并使用它来构建文件夹路径的其余部分。每个文件都有一个 我可以使用SxxExx部分来获取季节信息。我会 例如,将S01转换为第1季,成为文件夹的一部分 路径。

结果复制命令看起来像这样(使用上面的文件名)

cp Almost.Human.S01E01.720p.HDTV.X264.mkv shows/Almost Human/Season 1

我对sed或regex不够精明,无法正确使用语法    经过大量的搜索,没有人在任何例子中做到这一点    可以“借”来。

提前致谢!

更新

非常感谢Janos!他不仅提供了一个出色的解决方案,而且帮助我更多地使用正则表达式。

我对最终产品做了一些改动。在对Plex的命名约定要求进行一些研究之后,我将正则表达式调整为acommodate并且还内置了“文件存在”检查以避免不必要的传输。

这是我将在今晚晚些时候加入CRON的最终结果。

#!/bin/bash
readonly FILEPATH=~/downloads
readonly SAVEPATH=~/shows

for file in $FILEPATH/*.mkv
do
        dfile="$SAVEPATH/$(basename "$file" | sed -e 's/\./ /g' -e 's?\(.*\) [Ss]\([0-9][0-9]\)[Ee]\([0-9][0-9]\) .*?\1/Season \2/\1 - S\2E\3.mkv?')"

        if [ ! -f "$dfile" ]

        then
                cp -v "$file" "$dfile"
                mkdir -p "$(dirname "$dfile")"
        else
                echo "file exists "$dfile""
        fi

done

1 个答案:

答案 0 :(得分:2)

你可以这样做:

for file in $FILEPATH/*.mkv; do
    # get the destination filename
    dfile="$SAVEPATH/$(basename "$file" | sed -e 's/\./ /g' -e 's?\(.*\) S0\([0-9]\)E\([0-9][0-9]\) .*?\1/Season \2/Episode \3.mkv?')"

    # create the destination directory
    mkdir -p "$(dirname "$dfile")"

    cp "$file" "$dfile"
done

这将创建如下文件名:

Almost Human/Season 1/Episode 01.mkv

制作如下文件名:

Almost Human/Season 1/Almost Human Episode 01.mkv

然后像这样更改sed

sed -e 's/\./ /g' -e 's?\(.*\) S0\([0-9]\)E\([0-9][0-9]\) .*?\1/Season \2/\1 Episode \3.mkv?

此解决方案中的关键是捕获 \(...\)中名称的相关部分,然后使用\1为第一个{{1}引用这些捕获的匹配},\(...\)表示第二个,依此类推。