I want to loop over the indices of an array starting on the second index. How can I do this?
I have tried:
myarray=( "test1" "test2" "test3" "test4")
for i in ${!myarray[@]:1}
do
# I only print the indices to simplify the example
echo $i
done
But doesn't work.
Obviously this works:
myarray=( "test1" "test2" "test3" "test4")
myindices=("${!myarray[@]}")
for i in ${myindices[@]:1}
do
echo $i
done
But I would like to combine everything in the for loop statement if possible.
Use the # parameter length expansion:
myarray=( "test1" "test2" "test3" "test4")
for (( i=1; i < ${#myarray[@]}; i++ ))
do
# only print the indices to simplify the example
echo $i
done
Note that the ! indirect expansion operator is evidently not compatible with substring expansion since:
echo "${!myarray[@]:2}"
Produces an error code 1 and outputs to STDERR:
bash: test1 test2 test3 test4: bad substitution
At least for current versions of bash, v.4.4 and earlier. Unfortunately man bash doesn't make it sufficiently clear that substring expansion doesn't work with indirect expansion.
I'd do it this way:
#!/usr/bin/env bash
myarray=('a' 'b' 'c' 'd')
start_index=2
# generate a null delimited list of indexes
printf '%s\0' "${!myarray[@]}" |
# slice the indexes list 2nd entry to last
cut --zero-terminated --delimiter='' --fields="${start_index}-" |
# iterate the sliced indexes list
while read -r -d '' i; do
echo "$i"
done
Output does not list first index 0 as expected:
1
2
3
Works as well with an associative array:
#!/usr/bin/env bash
typeset -A myassocarray=(["foo"]='a' ["bar"]='b' ["baz"]='c' ["qux"]='d')
start_index=2
# generate a null delimited list of indexes
printf '%s\0' "${!myassocarray[@]}" |
# slice the indexes list 2nd entry to last
cut --zero-terminated --delimiter='' --fields="${start_index}-" |
# iterate the sliced indexes list
while read -r -d '' k; do
echo "$k"
done
Output:
bar
baz
qux
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With