我遇到了一个问题。下面是我的用于合并视频和字幕的 bash 脚本:
#!/bin/bash
cd /media/ptrknvk/'TOSHIBA EXT'/Shows/My/'Doctor Who'/
url0='DW s11e0'
url1='DW\ s11e'
for(( i=1; i<11; i++ ))
do
if ! [ $i -gt 9 ];
then
mkvmerge -o $url0$i.mkv $url0$i.mkv $url0$i.srt
rm $url0$i.srt
else
mkvmerge -o $url1$i.mkv $url1$i.mkv $url1$i.srt
rm $url1$i.srt
fi
done
文件的名称例如为“DW s11e05.mkv”,并且它们实际上存在于目录中。
结果如下:
mkvmerge v8.8.0 ('Wind at my back') 64bit
Error: The file 's11e09.mkv' could not be opened for reading: open file error.
rm: cannot remove 'DW': No such file or directory
rm: cannot remove 's11e09.srt': No such file or directory
mkvmerge v8.8.0 ('Wind at my back') 64bit
Error: The file 's11e10.mkv' could not be opened for reading: open file error.
rm: cannot remove 'DW\': No such file or directory
rm: cannot remove 's11e10.srt': No such file or directory
如您所见,空格前的 '\' 在这里不起作用。我也尝试使用 echo,但没有任何变化(mb 我以错误的方式使用它)。
抱歉我的风格有点菜鸟。
答案1
你需要引用你的变量. 这应该可以实现你想要的效果:
#!/bin/bash
cd /media/ptrknvk/'TOSHIBA EXT'/Shows/My/'Doctor Who'/
url0='DW s11e0'
url1='DW s11e'
for(( i=1; i<11; i++ ))
do
if ! [ $i -gt 9 ];
then
mkvmerge -o "$url0$i.mkv" "$url0$i.mkv" "$url0$i.srt" &&
rm "$url0$i.srt"
else
mkvmerge -o "$url1$i.mkv" "$url1$i.mkv" "$url1$i.srt" &&
rm "$url1$i.srt"
fi
done
请注意,我还在&&
每个mkvmerge
命令后添加了一个,因此rm
只有在成功时才会运行mkvmerge
。如果合并失败,您不想删除字幕文件!
话虽如此,尽管您的方法没有任何问题,但我觉得您可以使用 shell 通配符使它变得更简单、更优雅:
#!/bin/bash
for file in "/media/ptrknvk/TOSHIBA EXT/Shows/My/Doctor Who/"DW*mkv; do
srtFile=${file//.mkv/.srt}
mkvmerge -o "$file" "$file" "$srtFile" && rm "$srtFile"
done
你甚至不需要脚本。你可以直接在终端中以一行代码运行它:
for file in "/media/ptrknvk/TOSHIBA EXT/Shows/My/Doctor Who/"DW*mkv; do
mkvmerge -o "$file" "$file" "${file//.mkv/.srt}" && rm "${file//.mkv/.srt}";
done
答案2
引用变量以防止分词。顺便说一下,整个字符串使用双引号是首选样式。
#!/bin/bash
# Also exit if this fails
cd "/media/ptrknvk/TOSHIBA EXT/Shows/My/Doctor Who/" || exit
url0="DW s11e0"
url1="DW s11e"
for (( i=1; i<11; i++ )); do
# Also why use "not greater-than" when "less-than-or-equal" exists?
if [ $i -le 9 ]; then
# Also you can DRY* out this part with variables.
url="$url0"
else
url="$url1"
fi
# Also when concatenating variables, it's clearer to use the "${var}" style. **
f_mkv="${url}${i}.mkv"
f_srt="${url}${i}.srt"
mkvmerge -o "$f_mkv" "$f_mkv" "$f_srt"
rm "$f_srt"
done
壳牌检测对于在 shell 脚本中查找此类问题非常有用。
* 干燥 =不要重复自己
** 或者你也可以使用printf -v
,但在这种情况下这并不是很大的改进。例如
printf -v f_mkv "%s%s.mkv" "$url" $i