组合多个参数扩展的正确语法是什么?
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
您不能组合多个参数扩展,但是...
...你可以简化这段代码!
最大的收获是使用现有的工具。
- 让我们使用
grep
而不是循环。它应该在出现 RegEx 模式时做一些事情,所以:
grep -E "$rbv_reg" "" # -E is for extended RegEx
- 我猜你的模式不区分大小写,所以让我们用
-i
标志禁用它。
- 匹配后循环中断,所以让我们传递
-m 1
以在第一次匹配后停止处理文件。
- 您想将大写字母转换为小写字母,所以让我们通过
tr
:
grep -m 1 -E -i "$rbv_reg" "" | tr '[:upper:]' '[:lower:]'
- 然后用
//[^0-9a-z\.\-]/
替换一些字符,将其通过管道传输到 sed
即可:
grep -m 1 -E -i "$rbv_reg" "" | tr '[:upper:]' '[:lower:]' | sed 's/[^0-9a-z\.\-]//g'
- 最后,让我们获取变量的输出:
ruby_version="$( grep -m 1 -E -i '$rbv_reg' '' | tr '[:upper:]' '[:lower:]' | sed 's/[^0-9a-z\.\-]//g' )"
- 既然你要打印新行,让我们使用简单的
echo
而不是 printf
- 剩下的就是
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.
中工作
我当前的代码:
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
您不能组合多个参数扩展,但是...
...你可以简化这段代码!
最大的收获是使用现有的工具。
- 让我们使用
grep
而不是循环。它应该在出现 RegEx 模式时做一些事情,所以:
grep -E "$rbv_reg" "" # -E is for extended RegEx
- 我猜你的模式不区分大小写,所以让我们用
-i
标志禁用它。 - 匹配后循环中断,所以让我们传递
-m 1
以在第一次匹配后停止处理文件。 - 您想将大写字母转换为小写字母,所以让我们通过
tr
:
grep -m 1 -E -i "$rbv_reg" "" | tr '[:upper:]' '[:lower:]'
- 然后用
//[^0-9a-z\.\-]/
替换一些字符,将其通过管道传输到sed
即可:
grep -m 1 -E -i "$rbv_reg" "" | tr '[:upper:]' '[:lower:]' | sed 's/[^0-9a-z\.\-]//g'
- 最后,让我们获取变量的输出:
ruby_version="$( grep -m 1 -E -i '$rbv_reg' '' | tr '[:upper:]' '[:lower:]' | sed 's/[^0-9a-z\.\-]//g' )"
- 既然你要打印新行,让我们使用简单的
echo
而不是printf
- 剩下的就是
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.
中工作