问题描述
是否可以使用Bash的内置模式匹配和参数替换从字符串的开头 中删除模式? (重击5.0.18)
给出以下数组:
myparams=( --some-param -h --15 -q 100 )
我想遍历元素并输出以下内容(从前面剥离所有-
,而不会影响后面的任何内容)。所需的输出:
some-param
h
15
q
100
我知道Bash Hackers Wiki - Substring removal,但是我看不到任何方法。
这是一次失败的尝试,几乎有效,但是some-
遭到破坏:
$ for p in "${myparams[@]}"; do echo "$p ==> ${p##*-}" ; done
--some-param ==> param
-h ==> h
--15 ==> 15
-q ==> q
100 ==> 100
另一次失败的尝试,这次some-param
变成了someparam
:
$ for p in "${myparams[@]}"; do echo "$p ==> ${p//-}" ; done
--some-param ==> someparam
-h ==> h
--15 ==> 15
-q ==> q
100 ==> 100
这是一个可行的解决方案,但它依赖于sed
(经macOS 10.15.7的sed测试):
$ for p in "${myparams[@]}"; do echo "$p ==> $(sed 's/^-*//'<<<"$p")" ; done
--some-param ==> some-param
-h ==> h
--15 ==> 15
-q ==> q
100 ==> 100
最后,这是一种使用BASH_REMATCH
的有效方法-这是唯一的内置方法吗?:
$ for p in "${myparams[@]}"; do [[ $p =~ ^(-*)?(.*) ]]; echo "$p ==> ${BASH_REMATCH[2]}" ; done
--some-param ==> some-param
-h ==> h
--15 ==> 15
-q ==> q
100 ==> 100
解决方法
使用扩展模式和参数扩展:
shopt -s extglob
printf '%s\n' "${myparams[@]##+(-)}"
-
+(-)
匹配一个或多个破折号 -
#
仅在值的开头删除字符串 -
##
匹配可能的最长字符串 - 使用数组作为参数会从其所有成员中删除前缀