Reputation: 3833
I found an awesome answer on StackOverflow which explains how to pass an associative array to a function. Would someone be able to help me figuring out what the syntax of ${1#*=}
in the code below specifies? (Borrowed from that answer by jaypal singh):
#!/bin/bash
declare -A weapons=(
['Straight Sword']=75
['Tainted Dagger']=54
['Imperial Sword']=90
['Edged Shuriken']=25
)
function print_array {
eval "declare -A arg_array="${1#*=}
for i in "${!arg_array[@]}"; do
printf "%s\t%s\n" "$i ==> ${arg_array[$i]}"
done
}
print_array "$(declare -p weapons)"
Here's my guess so far (correct me if I'm wrong on any of these):
- 1
means the first parameter passed to the function ($1
or ${1}
)
- #
means the index of $1
, which, since $1
is an associative array, makes #
the keys of $1
- *
means the values of of the #
keys in associate array $1
That leaves the =
. What does that signify? Is that like a way to show that you want #
and *
to mean the keys and values of the associate array?
Upvotes: 5
Views: 7120
Reputation: 7035
The snippet ${1#*=}
has nothing to do with associative arrays.* (Bash's syntax is super consistent, and not at all confusing)
This is a pattern match on the value of the first argument (${1}
) of your function or script. Its syntax is
${variable#glob}
where
variable
is any bash variableIt deletes the shortest match, starting at the beginning of the line.
There is also ##
which deletes the longest match starting from the beginning of the variable, %
, which deletes the shortest match starting from the end, and %%
, which deletes the longest match starting from the end.
So, for example, the following code:
myVar="abc=llamas&disclaimer=true"
echo "${myVar#*=}"
will print llamas&disclaimer=true
to the screen.
On the other hand,
myVar="abc=llamas&disclaimer=true"
echo ${myVar##*=}
will print true
, and
myVar="foobar is bad"
echo "${myVar%%b*}"
will print foo
* This is fully explained in the bash man page; just search for the string ${parameter#word}
to find it
Upvotes: 14
Reputation: 22428
It deletes the string matched (shortest match from start) by pattern *=
in the string evaluated by $1
.
$1
is the first positional parameter passed to the shell.
The general format can be written as ${var#patt}
too, where patt
is matched (shortest match from start) in $var
and deleted.
Example:
var="first=middle=last"
echo "${var#*=}"
Output:
middle=last
If ##
is used instead of #
i.e ${var##pat}
, then the pat
is matched for the longest match (from start).
Example:
var="first=middle=last"
echo "${var##*=}"
Output:
last
${parameter#word}
${parameter##word}
The word is expanded to produce a pattern just as in filename expansion (see Filename Expansion). If the pattern matches the beginning of the expanded value of parameter, then the result of the expansion is the expanded value of parameter with the shortest matching pattern (the ‘#’ case) or the longest matching pattern (the ‘##’ case) deleted. If parameter is ‘@’ or ‘’, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with ‘@’ or ‘’, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list.
Upvotes: 6