在 ${} 上下文中 /#/ 符号是什么意思?

在 ${} 上下文中 /#/ 符号是什么意思?

在以下函数的上下文中

function foo { local d="d"; printf "%s" "${@/#/$d}"; }

这是什么/#/意思?

当我调用它时foo a b c它返回dadbdc

答案1

在你的代码中/#/属于"${@/#/$d}"。这是关于什么参数扩展可以在 Bash 中执行。

${parameter/pattern/string}
pattern扩展以产生一个模式,就像文件名扩展一样。被扩展并且与其值parameter的最长匹配被替换为。[…] 如果以开头,它必须与扩展值的开头匹配。[…]patternstringpattern#parameter

#aspattern应解释为以#开头为锚点,加上一个空字符串作为实际要匹配的模式。它匹配开头的一个空字符串。

string本身会经历参数扩展(尽管引用的片段没有明确说明这一点)。在您的代码中$d扩展为d

如果是${parameter/#/$d}d则会在 的扩展值开头替换一个空字符串parameter。换句话说,d将在扩展值前面加上前缀。这适用于parameter保留空字符串的情况(结果将只是d),但不适用于parameter未设置的情况(结果仍为空,就像任何未设置的参数一样,d不会被添加)。

在您的代码中, 代替@parameterSimple$@扩展为从 1 开始的所有位置参数(如果第一个参数未设置,则扩展为零)。"$@"扩展为所有位置参数,其中每个位置参数的行为都像单独用双引号引起来一样。 同样地,${@/#/d}扩展为所有位置参数,其中每个位置参数都位于d前面;并且如果$d扩展为d${@/#/$d}则会给出相同的结果。 最后"${@/#/$d}"扩展为所有位置参数,其中每个位置参数都位于d前面并且行为都像单独用双引号引起来一样。

因此,当你运行foo a b cprintf "%s" "${@/#/$d}"相当于

printf "%s" "da" "db" "dc"

注意${parameter/pattern/string}语法是不是指定POSIX

答案2

"${@/#/$d}"由 Bash 以下列方式扩展:

  1. @foo指的是参数数组,因此如果你调用类似的函数foo "a b" c,那么参数数组有两个条目a bc
  2. "${varname/pattern/replacement}"(模式替换)用替换pattern变量中的第一个实例。varnamereplacement
  3. #在模式替换中匹配变量值的开头而不是文字字符串“#”。
  4. $d是一个简单的变量引用,并且会扩展为变量的值d

总之,这将扩展到每个函数参数,然后在每个参数之前插入变量的值d。 这些参数中的每一个都以无格式(重要的是没有分隔符)的方式打印printf

这个函数的一个好名字可能是prefix_join,因为它基本上为每个参数加上前缀,然后将它们连接起来。

相关内容