What special meaning does “#” have within a parameter-expansion pattern

wildcardszsh

Suppose I’ve defined a variable like

number=123#456

and I want to print it without the leading “123#”. (This kind of thing happens in zsh when you’re working with numbers in bases other than 10.) The “Parameter Expansion” section of the manual says,

${name#pattern}

${name##pattern}

If the pattern matches the beginning of the value of name, then substitute the value of name with the matched portion deleted; otherwise, just substitute the value of name. In the first form, the smallest matching pattern is preferred; in the second form, the largest matching pattern is preferred.

This suggests to me that I should be able to say

print ${number#123#}

to get rid of the “123#”, but this actually outputs “3#456”. I found that I can get the desired effect if I escape the “#” that I’m trying to remove:

print ${number#123\#}    # prints "456"

What was the special meaning that the “#” had before I escaped it?

Best Answer

# is a glob operator that means “zero or more occurrences of the preceding character or parenthesized group”. It's the zsh way of writing the * regex operator. Hence 123# matches 12 at the start of 123#456 when taking the shortest match (${number#123#}) and it matches 123 when taking the longest match (${number##123#}).

The # operator is only active when the extended_glob option is set. This option is not set by default, but it's common to set it in your configuration (because it's pretty useful and largely non-annoying), and it's always set while executing completion functions.

Related Question