问题
I thought I understood the use of the optional ?(pattern-list)
in bash (when extglob
shell option is on) and by default in ksh. For example in bash
:
$ shopt -s extglob
$ V=35xAB
$ echo "${V#?(35|88)x}" "${V#35}"
AB xAB
But when the matching prefix pattern is just one ?()
or one *()
, which introduce what I call optional patterns, the 35
is not omitted unless ##
is used:
$ echo "${V#?(35|88)}" "${V#*(35|88)}" # Why 35 is not left out?
35xA 35xA
$ echo "${V##?(35|88)}" "${V##*(35|88)}" # Why is it omitted when ## is used?
xA xA
The same behaviour is reported when ?()
and *()
are used in a matching suffix pattern (using %
and %%
):
$ echo "${V%5?(xA|Bz)}" # 5xA is omitted
3
$ echo "${V%?(xA|Bz)}" "${V%*(xA|Bz)}" # why xA is not left out?
35xA 35xA
$ echo "${V%%?(xA|Bz)}" "${V%%*(xA|Bz)}" # xA is omitted when %% is used
35 35
I tested this issue in the bash
releases 3.2.25, 4.1.2 and 4.1.6 and it makes me think that, perhaps, I had not properly understood the actual underlying shell mechanism for matching patterns.
May anybody shed light on this?
Thanks in advance
回答1:
If you use @
instead of ?
then it works as expected:
$> echo "${V#@(35|88)}"
xAB
$> echo "${V%@(xAB|Bzh)}"
35
Similarly behavior of +
instead of *
:
$> echo "${V#*(35|88)}"
35xAB
$>echo "${V#+(35|88)}"
xAB
It is because:
?(pattern-list)
# Matches zero or one occurrence of the given patterns@(pattern-list)
# Matches one of the given patterns
And:
*(pattern-list)
# Matches zero or more occurrences of the given patterns+(pattern-list)
# Matches one or more occurrences of the given patterns
来源:https://stackoverflow.com/questions/39445699/how-does-extglob-work-with-shell-parameter-expansion