组合多个参数扩展的正确语法是什么?

What is the correct syntax to combine multiple parameter expansions?

我当前的代码:

while read -r rbv_line || [[ -n "$rbv_line" ]]; do
  if [[ "${rbv_line}" =~ ${rbv_reg} ]]; then
    rbv_downcase="${BASH_REMATCH[0],,}" &&
      ruby_version="${rbv_downcase//[^0-9a-z\.\-]/}" &&
      ((reg_matches="${reg_matches}"+1))
    printf "\n"
    printf "Setting Ruby version: %s\n" "${ruby_version}"
    break
  fi
done < "" 

它做我想做的。但是我很想知道我是否可以进一步简化这段代码,希望有人能帮助我理解语法。

如果你看到这两行:

rbv_downcase="${BASH_REMATCH[0],,}" &&
  ruby_version="${rbv_downcase//[^0-9a-z\.\-]/}" &&

最初我尝试使用如下方法将它们合并为一个:

ruby_version="${BASH_REMATCH[0],,//[^0-9a-z\.\-]/}"

那不行。

有没有办法结合这两个参数扩展(,,//[^0-9a-z\.\-]/)或者通过中间变量传递它是正确的方法?

您可以在这里查看最新版本的代码: https://github.com/octopusnz/scripts

您不能组合多个参数扩展,但是...


...你可以简化这段代码!

最大的收获是使用现有的工具。

  1. 让我们使用 grep 而不是循环。它应该在出现 RegEx 模式时做一些事情,所以:
grep -E "$rbv_reg" "" # -E is for extended RegEx
  1. 我猜你的模式不区分大小写,所以让我们用 -i 标志禁用它。
  2. 匹配后循环中断,所以让我们传递 -m 1 以在第一次匹配后停止处理文件。
  3. 您想将大写字母转换为小写字母,所以让我们通过 tr:
grep -m 1 -E -i "$rbv_reg" "" | tr '[:upper:]' '[:lower:]'
  1. 然后用 //[^0-9a-z\.\-]/ 替换一些字符,将其通过管道传输到 sed 即可:
grep -m 1 -E -i "$rbv_reg" "" | tr '[:upper:]' '[:lower:]' | sed 's/[^0-9a-z\.\-]//g'
  1. 最后,让我们获取变量的输出:
ruby_version="$( grep -m 1 -E -i '$rbv_reg' '' | tr '[:upper:]' '[:lower:]' | sed 's/[^0-9a-z\.\-]//g' )"
  1. 既然你要打印新行,让我们使用简单的 echo 而不是 printf
  2. 剩下的就是if [ -n "$ruby_version" ]增加reg_matches

最后,我们得到:

ruby_version="$(
    grep -m 1 -E -i '$rbv_reg' '' |
    tr '[:upper:]' '[:lower:]' |
    sed 's/[^0-9a-z\.\-]//g'
)"

if [ -n "$ruby_version" ]; then
    reg_matches="$((reg_matches+1))"
    echo
    echo "Setting Ruby version: $ruby_version"
fi

以上代码的优点是它实际上并不 Bash 依赖并且应该在任何 POSIX Bourne 兼容的 shell.

中工作