- Bash provides only 1 dimensional array.
- Bash provides both indexed array and associative arrays(also called as hashes in other languages)
- Any variables can be used as an indexed array.
- The declare builtin can be used to explicitly declare an array.
- There is no size limitations on array.
- Indexed Arrays dont need the members be indexed or assigned continously.
- Indexed arrays can be referenced using integers and are zero based.
- Associative Arrays use arbitrary strings.
- Following are two ways to create indexed arrays :
- Implicit way : Assign Value to any variable using below syntax
name[subscript]=value
The subscript is treated as an arithmetic expression that must
evaluate to a number.
- Explicit way: Use declare -a
declare -a name
Examples:
- Implicit method:
[sukul1@lldd010 ~]$ array2[1]=sukul
[sukul1@lldd010 ~]$ array2[0]=mahadik
[sukul1@lldd010 ~]$ declare -a
declare -a BASH_ARGC='()'
declare -a BASH_ARGV='()'
declare -a BASH_LINENO='()'
declare -a BASH_SOURCE='()'
declare -ar
BASH_VERSINFO='([0]="4" [1]="1" [2]="2"
[3]="1" [4]="release"
[5]="x86_64-redhat-linux-gnu")'
declare -a DIRSTACK='()'
declare -a FUNCNAME='()'
declare -a GROUPS='()'
declare -a
PIPESTATUS='([0]="0")'
declare -a array2='([0]="mahadik" [1]="sukul")'
- Explicit method:
[sukul1@lldd010 ~]$ declare -a array3
[sukul1@lldd010 ~]$
declare -a
declare -a
BASH_ARGC='()'
declare -a
BASH_ARGV='()'
declare -a
BASH_LINENO='()'
declare -a
BASH_SOURCE='()'
declare -ar
BASH_VERSINFO='([0]="4" [1]="1" [2]="2"
[3]="1" [4]="release"
[5]="x86_64-redhat-linux-gnu")'
declare -a
DIRSTACK='()'
declare -a
FUNCNAME='()'
declare -a
GROUPS='()'
declare -a
PIPESTATUS='([0]="0")'
declare -a array3='()'
[sukul1@lldd010 ~]$
The declare -a shows all the arrays defined in the
current environment.
- To create associative arrays we can use declare builtin.
declare -A name
Example:
[sukul1@lldd010 ~]$
declare -A AssoArray
[sukul1@lldd010 ~]$
declare -A
declare -A AssoArray='()'
declare -A
BASH_ALIASES='()'
declare -A
BASH_CMDS='()'
[sukul1@lldd010 ~]$
- Attributes may be specified for an array variable using the declare and readonly builtins. Each attribute applies to all members of an array.
Thus we can make arrays readonly.
[sukul1@lldd010 ~]$
declare -A AssoArray
[sukul1@lldd010 ~]$
declare -A
declare -A
AssoArray='()'
declare -A
BASH_ALIASES='()'
declare -A
BASH_CMDS='()'
[sukul1@lldd010 ~]$
declare -Ar readArray
[sukul1@lldd010 ~]$
readonly AssoArray
[sukul1@lldd010 ~]$
declare -A
declare -Ar AssoArray='()'
declare -A
BASH_ALIASES='()'
declare -A
BASH_CMDS='()'
declare -Ar readArray='()'
[sukul1@lldd010 ~]$
- Once Arrays
are created arrays can be assigned values one element at a time as shown
below:
[sukul1@lldd016 ~]$
declare -a arr1
[sukul1@lldd016 ~]$
arr1[0]=25
[sukul1@lldd016 ~]$
arr1[1]=34
[sukul1@lldd016 ~]$
declare -A ARR1
[sukul1@lldd016 ~]$
ARR1['name']=sukul
[sukul1@lldd016 ~]$
ARR1['surname']=mahadik
Other simpler way to do this is to use compound assignments of the form
name=(value1
value2 ... )
where each value is of the form [subscript]=string.
Indexed array assignments do not require anything but string.
When assigning to indexed arrays, if the optional
subscript is supplied, that index is assigned to starts at zero.
When assigning to an associative array, the subscript
is required.
Note that for indexed assigning values like this
would implicitly create the array itself. However note that does not work with
Associative arrays.
Associative arrays need to be created first before we
do such compound assignment.
[sukul1@lldd016 ~]$
declare -a arr2
[sukul1@lldd016 ~]$
arr2=(23 45 23 21 56)
[sukul1@lldd016 ~]$
declare -a
declare -a
arr2='([0]="23" [1]="45" [2]="23"
[3]="21" [4]="56")'
[sukul1@lldd016 ~]$
declare -A ARR2
[sukul1@lldd016 ~]$
ARR2=([name]=sukul [surname]=mahadik)
[sukul1@lldd016 ~]$
declare -A
declare -A
ARR2='([surname]="mahadik" [name]="sukul" )'
In below example we can see that compound assignment
can actually create indexed array, but that does not work with associative
arrays.
Associative arrays need declaration.
[sukul1@lldd016 ~]$
arr3=(p1 p2 p3 p4)
[sukul1@lldd016 ~]$
declare -a
declare -a
arr3='([0]="p1" [1]="p2" [2]="p3"
[3]="p4")'
[sukul1@lldd016 ~]$
ARR3=([surname]=mahadik)
[sukul1@lldd016 ~]$
declare -A
declare -A
ARR1='([surname]="mahadik" [name]="sukul" )'
declare -A
ARR2='([surname]="mahadik" [name]="sukul" )'
declare -A
BASH_ALIASES='()'
declare -A
BASH_CMDS='()'
[sukul1@lldd016 ~]$
declare -a
declare -a
ARR3='([0]="mahadik")'
We can see above that associative array was not
created implicitly using compound assignment method.
So remember that associative arrays need declaration.
- When assigning to or referencing an indexed array, if name is subscripted by a negative number, that number is interpreted as relative to
one greater than the maximum index of name, so negative indices count back
from the end of the array, and an index of -1 references the last
element.
However for some reason this does not seem to work on
my bash
[sukul1@lldd016 ~]$
echo ${arr2[1]}
45
[sukul1@lldd016 ~]$
echo ${arr2[-1]}
-bash: arr2: bad
array subscript
[sukul1@lldd016 ~]$
- Any element of an array may be referenced using ${name[subscript]}.
The braces are required to avoid conflicts with the
shell’s filename expansion operators.
Remember that the braces are required. Ex: 2nd
element of array arr2 is arr2[1] . So to check the value in it we need to put
${} around it, just as we do with variables.
But here remember that braces are always required.
- If the subscript is ‘@’ or ‘*’, the word expands to all members of the array name.
These subscripts differ only when the word appears
within double quotes.
If the word is double-quoted, ${name[*]} expands to a
single word with the value of each array member separated by the first
character of the IFS variable, and ${name[@]} expands each element of name to a
separate word.
[sukul1@lldd016 ~]$
echo ${arr2[*]}
23 45 23 21 56
[sukul1@lldd016 ~]$
echo ${arr2[@]}
23 45 23 21 56
Following shows the difference between * and when used in double quotes.
With * result is one single word.
[sukul1@lldd016 ~]$
for i in "${arr2[*]}"
> do
> echo $i
> done
23 45 23 21 56
[sukul1@lldd016 ~]$
for i in "${arr2[@]}"
> do
> echo $i
> done
23
45
23
21
56
[sukul1@lldd016 ~]$
This is analogous to the expansion of the special
parameters ‘@’ and ‘*’.
- ${#name[subscript]} expands to the length of ${name[subscript]}.
If subscript is ‘@’ or ‘*’, the expansion is the
number of elements in the array.
Following shows how to find length of an element of
array. Its no different that finding size of any other variable.
[sukul1@lldd016 ~]$
echo ${#ARR1[surname]}
7
[sukul1@lldd016 ~]$
echo ${ARR1[surname]}
mahadik
[sukul1@lldd016 ~]$
ARR1[surname] is nothing but a variable, just that
this variable is part of any array.
Following shows how to find the size of array
[sukul1@lldd016 ~]$
echo ${#ARR1[*]}
2
[sukul1@lldd016 ~]$
- Referencing an array variable without a subscript is equivalent to referencing with a subscript of 0.
[sukul1@lldd016 ~]$
echo ${arr2[0]}
23
[sukul1@lldd016 ~]$
echo $arr2
23
[sukul1@lldd016 ~]$
- It is possible to obtain the keys (indices) of an array as well as the values.
${!name[@]} and ${!name[*]} expand to the indices
assigned in array variable name.
The treatment when in double quotes is similar to the
expansion of the special parameters ‘@’ and ‘*’ within double quotes.
[sukul1@lldd016 ~]$
echo ${!arr2[*]}
0 1 2 3 4
- The unset builtin is used to destroy arrays. unset name[subscript] destroys the array element at index subscript.
unset name, where name is an array, removes the
entire array. A subscript of ‘*’ or ‘@’ also removes the entire array
- The declare, local, and readonly builtins each accept a -a option to specify an indexed array and a -A option to specify an associative array.
If both options are supplied, -A takes precedence.
- The read builtin accepts a -a option to assign a list of words read from the standard input to an array, and can read values from the standard input into individual array elements.
- The set and declare builtins display array values in a way that allows them to be reused as input.