当我打印一个变量时,用一个子字符串替换另一个子字符串,如中所述本文档,它的行为正确:
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"
是绝对必要的,但始终引用变量是一个好习惯。