We cannot imagine a programming language without the concept of arrays. It doesn’t matter how they are implemented among various languages. Instead arrays help us in consolidating data, similar or different, under one symbolic name.
Here as we are concerned about shell scripting, this article will help you in playing around with some shell scripts which make use of this concept of arrays.
Array Initialization and Usage
With newer versions of bash, it supports one-dimensional arrays. An array can be explicitly declared by the declare shell-builtin.
declare -a var
But it is not necessary to declare array variables as above. We can insert individual elements to array directly as follows.
var[XX]=<value>
where ‘XX’ denotes the array index. To dereference array elements use the curly bracket syntax, i.e.
${var[XX]}
Note: Array indexing always start with 0.
Another convenient way of initializing an entire array is by using the pair of parenthesis as shown below.
var=( element1 element2 element3 . . . elementN )
There is yet another way of assigning values to arrays. This way of initialization is a sub-category of the previously explained method.
array=( [XX]=<value> [XX]=<value> . . . )
We can also read/assign values to array during the execution time using the read shell-builtin.
read -a array
Now upon executing the above statement inside a script, it waits for some input. We need to provide the array elements separated by space (and not carriage return). After entering the values press enter to terminate.
To traverse through the array elements we can also use for loop.
for i in “${array[@]}” do #access each element as $i. . . done
The following script summarizes the contents of this particular section.
#!/bin/bash array1[0]=one array1[1]=1 echo ${array1[0]} echo ${array1[1]} array2=( one two three ) echo ${array2[0]} echo ${array2[2]} array3=( [9]=nine [11]=11 ) echo ${array3[9]} echo ${array3[11]} read -a array4 for i in "${array4[@]}" do echo $i done exit 0
Various Operations on Arrays
Many of the standard string operations work on arrays . Look at the following sample script which implements some operations on arrays (including string operations).
#!/bin/bash array=( apple bat cat dog elephant frog ) #print first element echo ${array[0]} echo ${array:0} #display all elements echo ${array[@]} echo ${array[@]:0} #display all elements except first one echo ${array[@]:1} #display elements in a range echo ${array[@]:1:4} #length of first element echo ${#array[0]} echo ${#array} #number of elements echo ${#array[*]} echo ${#array[@]} #replacing substring echo ${array[@]//a/A} exit 0
Following is the output produced on executing the above script.
apple apple apple bat cat dog elephant frog apple bat cat dog elephant frog bat cat dog elephant frog bat cat dog elephant 5 5 6 6 Apple bAt cAt dog elephAnt frog
I think there is no significance in explaining the above script in detail as it is self-explanatory. If necessary I will dedicate one part in this series exclusively on string manipulations.
Command Substitution with Arrays
Command substitution assigns the output of a command or multiple commands into another context. Here in this context of arrays we can insert the output of commands as individual elements of arrays. Syntax is as follows.
array=( $(command) )
By default the contents in the output of command separated by white spaces are plugged into array as individual elements. The following script list the contents of a directory, which are files with 755 permissions.
#!/bin/bash ERR=27 EXT=0 if [ $# -ne 1 ]; then echo "Usage: $0 <path>" exit $ERR fi if [ ! -d $1 ]; then echo "Directory $1 doesn't exists" exit $ERR fi temp=( $(find $1 -maxdepth 1 -type f) ) for i in "${temp[@]}" do perm=$(ls -l $i) if [ `expr ${perm:0:10} : "-rwxr-xr-x"` -eq 10 ]; then echo ${i##*/} fi done exit $EXT
Simulating Two-dimensional Arrays
We can easily represent a 2-dimensional matrix using a 1-dimensional array. In row major order representation elements in each row of a matrix are progressively stored in array indexes in a sequential manner. For an mXn matrix, formula for the same can be written as.
matrix[i][j]=array[n*i+j]
Look at another sample script for adding 2 matrices and printing the resultant matrix.
#!/bin/bash read -p "Enter the matrix order [mxn] : " t m=${t:0:1} n=${t:2:1} echo "Enter the elements for first matrix" for i in `seq 0 $(($m-1))` do for j in `seq 0 $(($n-1))` do read x[$(($n*$i+$j))] done done echo "Enter the elements for second matrix" for i in `seq 0 $(($m-1))` do for j in `seq 0 $(($n-1))` do read y[$(($n*$i+$j))] z[$(($n*$i+$j))]=$((${x[$(($n*$i+$j))]}+${y[$(($n*$i+$j))]})) done done echo "Matrix after addition is" for i in `seq 0 $(($m-1))` do for j in `seq 0 $(($n-1))` do echo -ne "${z[$(($n*$i+$j))]}\t" done echo -e "\n" done exit 0
Even though there are limitations for implementing arrays inside shell scripting, it becomes useful in a handful of situations, especially when we handle with command substitution. Looking from an administrative point of view, the concept of arrays paved the way for development of many background scripts in GNU/Linux systems.
will you please provide a solution to this?
Take a range from 0 – 100, find the digits that are repeated twice like 33, 77, etc and store them in an array.
Good collection of examples, especially command output assigning is nice. I wrote somewhat similar but more extensive article on arrays in BASH. Check it out here: wojnowski.net.pl/main/index/arrays-in-bash.
Regards
Hi,
I want print only first and third element of the array.
what is the echo command?
how to import multiple directory in array(run time log /var/log/ ) in runtime and check if directory is present or not ?
Hi Gulab,
Sorry for being late..Got stuck with some other work. I would assume that by this time you might have found an answer to your question. Anyway following is my pov.
You can always insert elements into array by referring to the index numbers as I have mentioned in the article. By run time if you mean to have some kind of looping, then you could increment index number for the array within the loop and insert elements one by one. Checking for directory existence is not at all a complex task and you have various methods to do so (easy way: use if conditional statement with test expression parameter -d).
is there any way to change the default index value 0 of array to 1..
Can you please specify the use case?
actually we can access an array element like below
array_name=(“name_1″,”name_2″,”name_3″,”name_4″,”name_5”)
echo array_name[0]
the above echo command prints “name_1”
but i would like to print name_1 by using below echo command
echo array_name[1]
Here my intention is change the array default index value 0 to 1. so that i can print first value of array by using array_name[1] instead of using array_name[0]
Sorry for the late reply:
Some corrections to your example mentioned below:
* Your array initialization is wrong. I assume your intention was to initialize array as follows,
# array_name=(name_1 name_2 name_3 name_4 name_5)
Array elements are by default separated by one or more white spaces.
* Your de-referencing of array elements is wrong. See the correct usage below,
# echo ${array_name[0]}
Now coming to your question:
Yes, it is possible. You need to initialize the array by referencing the index as,
# array_name=([1]=name_1 name_2 name_3 name_4 name_5)
This means
array_name[1] = name_1
array_name[2] = name_2
array_name[3] = name_3
array_name[4] = name_4
array_name[5] = name_5
Hope this solution is helpful.
Thanks for your reply. I got it what exactly i want. Actually i’m facing some issues while using arrays in for loop and while loop. In those for and while loops the loop count is starting from 1, at that time if i want to use an array inside that loop, then i need to increase array index value to 1 manually. Now your solution solves this. Now i can directly use array with in a loop which has loop count start from 1.
Thanks.
Excellent
Your examples are so good. Thanks.
nice to know the functionality of arrays.