1

I just discovered a weird behavior when indexing into bash arrays with unset elements. I make an array with these three elements:

$ arry[3]=a $ arry[4]=b $ arry[5]=c 

The array appears to be right:

$ echo ${#arry[@]} 3 $ echo ${!arry[@]} 3 4 5 

But if I try to get the first three values in the array, I get a for all of them:

$ echo ${arry[@]:0:1} a $ echo ${arry[@]:1:1} a $ echo ${arry[@]:2:1} a 

I have to use the actual keys to get the elements I set:

$ echo ${arry[@]:3:1} a $ echo ${arry[@]:4:1} b $ echo ${arry[@]:5:1} c 

It looks like with substring expansion "offset" means the actual array index, and if unset, Bash just keep scrolling until it finds a set element.

Acknowledging that, is there any straight forward way to get the nth value of an indexed array with some unset element?

3
  • What is the output of declare -p arry ?
    – user79743
    CommentedMar 9, 2016 at 20:42
  • Here is the output @BinaryZebra declare -a arry='([3]="a" [4]="b" [5]="c")'
    – Claudio
    CommentedMar 10, 2016 at 21:12
  • That clearly means that the only set values are at index 3, 4 and 5, Therefore, you do need to use those index in ${arry[@]:5:1}.
    – user79743
    CommentedMar 11, 2016 at 1:08

2 Answers 2

1

is there any straight forward way to get the nth value of an indexed array with some unset element?

Not without a temporary array I think:

a=([3]=2 [1]=12 [12]=4 [23]=5) a_indices=("${!a[@]}") third_element=${a[${a_indices[2]}]} 

or

a_normalized=("${a[@]}") third_element=${a_normalized[2]} 

That's a ksh heritage. ksh and bash are the only shells that I know where arrays are sparse (or in other words are associative arrays with keys limited to positive integers and numerically sorted on their keys).

The arrays of all other shells that I know (zsh, yash, fish, csh, tcsh, rc, es...) are normal arrays (and with indices starting at 1 like one (at least I) would expect, not 0).

    0

    According to the Parameter Expansion in Bash

    the :x returns the elements from that index to the end.

    the :x:y returns y elements from the first extraction.

    It has to be views one after the other.

    ar[2]=a ar[3]=b ar[5]=y ar[6]=z echo ${ar[@]:0} # a b z y echo ${ar[@]:0:3} # a b z echo ${ar[@]:4} # y z 

      You must log in to answer this question.

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.