使用 bash 处理文件链接中的空格

使用 bash 处理文件链接中的空格

我遇到了一个问题。下面是我的用于合并视频和字幕的 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

相关内容