我写了一个小脚本,解压缩当前目录中的所有*.zip
文件,只将*.srt
个文件目录提取到新创建的目录中。然后循环遍历当前目录中的所有*.mkv
文件以获取其名称,然后更改subs/*.srt
文件名以生成与*.mkv
文件名完全相同的新文件名。
当有一个zip文件和一个mkv文件时,该脚本可以工作,但是当有更多文件时,它会产生错误的文件名。 我无法追踪为什么会这样。现在我知道是什么时候。
修改
我设法缩小了以错误方式更改文件名的方案。 假设在当前目录中我们有三个* .mkv文件:(按字母顺序排序)
$ ls -1a *.mkv
Home.S06E10.1080p.BluRay.x264-PRINTER.mkv
Home.S06E11.1080p.BluRay.x264-PRINTER.mkv
Home.S06E12.1080p.BluRay.x264-PRINTER.mkv
和三个* .srt文件:
$ ls -1a *.srt
Home.S06E10.srt
Home.S06E11.BDRip.X264-PRINTER.srt
Home.S06E12.BDRip.X264-PRINTER.srt
当我运行脚本时,我得到:
subs/Home.S06E10.srt -> subs/Home.S06E10.1080p.BluRay.x264-PRINTER.srt
subs/Home.S06E10.1080p.BluRay.x264-PRINTER.srt -> subs/Home.S06E11.1080p.BluRay.x264-PRINTER.srt
subs/Home.S06E11.1080p.BluRay.x264-PRINTER.srt -> subs/Home.S06E12.1080p.BluRay.x264-PRINTER.srt
如您所见,Home.S06E10.srt
使用了两次
#!/usr/bin/env bash
mkdir -p subs
mkdir -p mkv-out
mkdir -p subs-bak
# unzip files, maybe there are subtitles in it...
for zip in *.zip; do
if [ -f "$zip" ]; then
unzip "$zip" -d subs "*.srt" >/dev/null
fi
done
# move all subtitles to subs catalog
for srt in *.srt; do
if [ -f "$srt" ]; then
mv "*.srt" subs
fi
done
mkvCount=(*.mkv)
srtCount=(subs/*.srt)
if [ ${#mkvCount[@]} != ${#srtCount[@]} ]; then
echo "Different number of srt and mkv files!"
exit 1
fi
for MOVIE in *.mkv; do
for SUBTITLE in subs/*.srt; do
NAME=$(basename "$MOVIE" .mkv)
SRT="subs/$NAME.srt"
if [ ! -f "$SRT" ]; then
echo "$SUBTITLE -> ${SRT}"
mv "$SUBTITLE" "$SRT"
fi
done
done
答案 0 :(得分:1)
您似乎依赖文件的词典顺序将一个SRT与一个MKV相关联。如果您拥有的是同一系列的季节剧集文件,那么我建议采用完全不同的方法:迭代一个季节和一集剧集,然后以S ## E ##的形式生成面具并找到一个电影和一个字幕文件。如果你找到它们,就移动它们。
for season in {01..06}; do
for episode in {01..24}; do
# Count how many movies and subtitles we have in the form S##E##
nummovies=$(find -name "*S${season}E${episode}*.mkv" | wc -l)
numsubs=$(find -name "*S${season}E${episode}*.srt" | wc -l)
if [[ $nummovies -gt 1 || $numsubs -gt 1 ]]; then
echo "Multiple movies/subtitles for S${season}E${episode}"
exit 1
fi
# Skip if there is no movie or subtitle for this particular
# season/episode combination
if [[ $nummovies -eq 0 ]]; then
continue
fi
if [[ $numsubs -eq 0 ]]; then
echo "No subtitle for S${season}E${episode}"
continue
fi
# Now actually take the MKV file, get its basename, then find the
# SRT file with the same S##E## and move it
moviename=$(find -name "*S${season}E${episode}*.mkv")
basename=$(basename -s .mkv "$moviename")
subfile=$(find -name "*S${season}E${episode}*.srt")
mv "${subfile}" "${basename}.mkv"
done
done
如果您不想重写所有内容,只需更改上一个循环:
sed
查找特定的S ## E ## substring find
查找我的代码中的一个SRT文件这样做的好处是不依赖于硬编码的季节/剧集数量。我猜到了六季,没有超过26集的季节。但是,我认为我的代码会做,看起来会更简单。
确保只有一个SRT文件。拥有零个或多个文件可能只会从mv
给出错误,但最好是安全的。在我的代码中,我使用find
单独调用wc
来计算行数,但如果你对bash-foo更了解,那么也许有办法处理{{find
的输出。 1}}作为数组而不是。
在我的建议中,您也可以放弃#movies =#subtitles的检查。这为您提供了更大的灵活性字幕可以在您想要的任何目录中,但是电影被假定为CWDIR中的电影。使用find
,您还可以使用-or
运算符接受其他扩展程序,例如AVI和MPG。