Is it possible to remove a pattern from only the beginning of a string using Bash's built-in pattern matching and parameter substitution? (Bash 5.0.18)
Given the following array:
myparams=( --some-param -h --15 -q 100 )
I would like to loop through the elements and output the following (strip all -
s from the front without affecting any that might come after). Desired output:
some-param
h
15
q
100
I am aware of Bash Hackers Wiki - Substring removal but I didn't see any way to do this.
Here is one failed attempt, Almost works, but some-
gets clobbered:
$ for p in "${myparams[@]}"; do echo "$p ==> ${p##*-}" ; done
--some-param ==> param
-h ==> h
--15 ==> 15
-q ==> q
100 ==> 100
Another failed attempt, this time some-param
becomes someparam
:
$ for p in "${myparams[@]}"; do echo "$p ==> ${p//-}" ; done
--some-param ==> someparam
-h ==> h
--15 ==> 15
-q ==> q
100 ==> 100
Here's a working solution, but it relies on sed
(tested with sed from macOS 10.15.7):
$ for p in "${myparams[@]}"; do echo "$p ==> $(sed 's/^-*//'<<<"$p")" ; done
--some-param ==> some-param
-h ==> h
--15 ==> 15
-q ==> q
100 ==> 100
And finally, here's a working method that uses BASH_REMATCH
— is this the only builtin way?:
$ for p in "${myparams[@]}"; do [[ $p =~ ^(-*)?(.*) ]]; echo "$p ==> ${BASH_REMATCH[2]}" ; done
--some-param ==> some-param
-h ==> h
--15 ==> 15
-q ==> q
100 ==> 100
Use an extended pattern and parameter expansion:
shopt -s extglob
printf '%s\n' "${myparams[@]##+(-)}"
+(-)
matches one or more dashes#
removes the string only at the beginning of the value##
matches the longest string possible