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

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

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

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

例如:差不多.Human.S01E01.720p.HDTV.X264.mkv

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

我能够从文件名中提取显示文件夹名称。

#!/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 

问题:

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

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

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

我没有足够的sed或正则expression式来获得正确的语法,并经过大量的search,没有人是这样做的任何例子中,我可以“借”。

提前致谢!

UPDATE

非常感谢Janos! 他不仅提供了一个很好的解决scheme,而且帮助我更多地使用正则expression式。

我对最终产品做了一些改变。 在对Plex的命名约定要求进行了一些研究之后,我调整了正则expression式,并build立了一个“文件存在”检查以避免不必要的转换。

以下是今晚晚些时候我将joinCRON的最终结果。

 #!/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 

你可以做这样的事情:

 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为第一个\(...\)\2为第二个,等等。