bash 字符串替换的行为不一致

bash 字符串替换的行为不一致

当我打印一个变量时,用一个子字符串替换另一个子字符串,如中所述本文档,它的行为正确:

stringZ='abc - 123'

echo $stringZ             # abc - 123

echo ${stringZ/ - /test}  # abctest123

但是,如果我从文件名中获取字符串,则替换将被完全忽略:

for f in mp3/*; do

    stringZ=$(basename $f)

    echo $stringZ             # abc - 123.txt

    echo ${stringZ/ - /test}  # abc - 123.txt

done

如何替换从文件名派生的变量中的子字符串?

答案1

和往常一样,答案是你需要总是引用你的变量:

$ ls -N mp3/
abc - 123.txt

现在,让我们尝试一下你的循环:

$ for f in mp3/*; do 
    stringZ=$(basename $f); 
    echo $stringZ; 
    echo ${stringZ/ - /test} ; 
done
basename: extra operand ‘123.txt’
Try 'basename --help' for more information.

发生的情况是$f变量的值为mp3/abc - 123.txt,因此您正在运行basename mp3/abc - 123.txt并且会抱怨,因为它看到了空格并假设这mp3/abc是第一个参数。如果您引用以下内容,它应该按预期工作:

$ for f in mp3/*; do 
    stringZ=$(basename "$f"); 
    echo "$stringZ"; 
    echo "${stringZ/ - /test}" ; 
done
abc - 123.txt
abctest123.txt

这里只有引号basename "$f"是绝对必要的,但始终引用变量是一个好习惯。

相关内容