No. You can only index a simple array with an integer in bash. Associative arrays (introduced in bash 4) can be indexed by strings. They don't, however, provided for the type of reverse lookup you are asking for, without a specially constructed associative array.
#!/bin/bash
my_array=(red orange green)
value='green'
for i in "${!my_array[@]}"; do
if [[ "${my_array[$i]}" = "${value}" ]]; then
echo "${i}";
fi
done
Obviously, if you turn this into a function (e.g. get_index() ) - you can make it generic
This is just another way to initialize an associative array as chepner showed.
Don't forget that you need to explicitly declare or typset an associative array with -A attribute.
This shows some methods for returning an index of an array member.
The array uses non-applicable values for the first and last index,
to provide an index starting at 1, and to provide limits.
The while loop is an interesting method for iteration, with cutoff,
with the purpose of generating an index for an array value,
the body of the loop contains only a colon for null operation.
The important part is the iteration of i until a match,
or past the possible matches.
The function indexof() will translate a text value to an index.
If a value is unmatched the function returns an error code that can be
used in a test to perform error handling.
An input value unmatched to the array will exceed the range limits (-gt, -lt) tests.
There is a test (main code) that loops good/bad values, the first 3 lines are commented out, but try some variations to see interesting results (lines 1,3 or 2,3 or 4). I included some code that considers error conditions, because it can be useful.
The last line of code invokes function indexof with a known good value "green" which will echo the index value.
indexof(){
local s i;
# 0 1 2 3 4
s=( @@@ red green blue @o@ )
while [ ${s[i++]} != $1 ] && [ $i -lt ${#s[@]} ]; do :; done
[ $i -gt 1 ] && [ $i -lt ${#s[@]} ] || return
let i--
echo $i
};# end function indexof
# --- main code ---
echo -e \\033c
echo 'Testing good and bad variables:'
for x in @@@ red pot green blue frog bob @o@;
do
#v=$(indexof $x) || break
#v=$(indexof $x) || continue
#echo $v
v=$(indexof $x) && echo -e "$x:\t ok" || echo -e "$x:\t unmatched"
done
echo -e '\nShow the index of array member green:'
indexof green
function array_indexof() {
[ $# -lt 2 ] && return 1
local a=("$@")
local v="${a[-1]}"
unset a[-1]
local i
for i in ${!a[@]}; do
if [ "${a[$i]}" = "$v" ]; then
echo $i
return 0 # stop after first match
fi
done
return 1
}
a=(a b c d)
i=$(array_indexof "${a[@]}" d)
echo $i # 3
(?=string) is called a positive lookahead which allows matching something (in our case a number) followed by something else which won't be added to the result.