关于 bash 参数替换的困惑

Confusion about bash parameter substitution

我有一个脚本可以重命名一个文件或一系列包含特定字符串的文件

for i in "${@:3}"; do
        mv -- "$i" "${i//}"
done

所以当我这样做时

bash script_name patter_1 pattern_2 string*

它确实有效,但当我尝试时:

mv -- "$i" "${i///}"  

它仍然有效

${i//} 

${i///} 

为什么会这样,我搜索了 bash 初学者指南,但仍然没有任何线索。谢谢

来自bash manual

${parameter/pattern/string}

The pattern is expanded to produce a pattern just as in filename expansion. Parameter is expanded and the longest match of pattern against its value is replaced with string. If pattern begins with ‘/’, all matches of pattern are replaced with string

所以如果替换只能完成一次,那么这些是等价的:

${parameter/pattern/string}
           ^
${parameter//pattern/string}
           ^^

看例子:

$ i="hello"
$ echo ${i/e/XX}  #just one replacement
hXXllo            # <----------------------
$ echo ${i//e/XX} # multiple replacements  | they are the same
hXXllo            # <----------------------
$ echo ${i/l/XX}  #just one replacement
heXXlo            # it just happens once!
$ echo ${i//l/XX} #multiple replacements
heXXXXo           # it happens many times!