Using Arrays in Bash
Arrays to the rescue!
So far, you have used a limited number of variables in your bash script, you have created a few variables to hold one or two filenames and usernames.
But what if you need more than a few variables in your bash scripts; let’s say you want to create a bash script that reads a hundred different inputs from a user, are you going to create 100 variables?
Luckily, you don’t need to because arrays offer a much better solution.
Creating your first array in a bash script
Let’s say you want to create a bash script timestamp.sh that updates the timestamp of five different files.
First, use the naïve approach of using five different variables:
#!/bin/bash
file1="f1.txt"
file2="f2.txt"
file3="f3.txt"
file4="f4.txt"
file5="f5.txt"
touch $file1
touch $file2
touch $file3
touch $file4
touch $file5
Now, instead of using five variables to store the value of the five filenames, you create an array that holds all the filenames, here is the general syntax of an array in bash:
array_name=(value1 value2 value3 … )
So now you can create an array named files that stores all the five filenames you have used in the timestamp.sh script as follows:
files=("f1.txt" "f2.txt" "f3.txt" "f4.txt" "f5.txt")
As you can see, this is much cleaner and more efficient as you have replaced five variables with just one array!
Accessing array elements in bash
The first element of an array starts at index 0
and so to access the nth element of the array you use the n -1
index.
For example, to print the value of the 2nd element of your files array, you can use the following echo statement:
echo ${files[1]}
and to print the value of the 3rd element of your files array, you can use:
echo ${files[2]}
and so on.
The following bash script reverse.sh would print out all the five values in your files array in reversed order, starting with the last array element:
#!/bin/bash
files=("f1.txt" "f2.txt" "f3.txt" "f4.txt" "f5.txt")
echo ${files[4]}
echo ${files[3]}
echo ${files[2]}
echo ${files[1]}
echo ${files[0]}
I know you might be wondering why so many echo statements and why don't I use a loop here. This is because I intend to introduce bash loop concepts later in this series.
You can also print out all the array elements at once:
echo ${files[*]}
f1.txt f2.txt f3.txt f4.txt f5.txt
You can print the total number of the files array elements, i.e. the size of the array:
echo ${#files[@]}
5
You can also update the value of any element of an array; for example, you can change the value of the first element of the files array to “a.txt” using the following assignment:
files[0]="a.txt"
Adding array elements in bash
Let’s create an array that contains the name of the popular Linux distributions:
distros=("Ubuntu" "Red Hat" "Fedora")
The distros array current contains three elements. You can use the +=
operator to add (append) an element to the end of the array.
For example, you can append Kali to the distros array as follows:
distros+=("Kali")
Now the distros array contains exactly four array elements, with Kali being the last element of the array.
Deleting array elements in bash
Let’s first create a num array that will store the numbers from 1 to 5:
num=(1 2 3 4 5)
You can print all the values in the num array:
echo ${num[*]}
1 2 3 4 5
You can delete the 3rdelement of the num array by using the unset
shell built-in:
unset num[2]
Now, if you print all the values of the num array:
echo ${num[*]}
1 2 4 5
As you can see, the third element of the array num has been deleted.
You can also delete the whole num array in the same way:
unset num
Creating hybrid arrays with different data types
In bash, unlike many other programming languages, you can create an array that contains different data types. Take a look at the following user.sh bash script:
#!/bin/bash
user=("john" 122 "sudo,developers" "bash")
echo "User Name: ${user[0]}"
echo "User ID: ${user[1]}"
echo "User Groups: ${user[2]}"
echo "User Shell: ${user[3]}"
Notice the user array contains four elements:
- "John" ----> String Data Type
- 122 ---> Integer Data Type
- "sudo,developers" ---> String Data Type
- "bash" ---> String Data Type
So, it’s totally ok to store different data types in the same array. Isn't that awesome?
This takes us to the end of this tutorial; I hope you enjoyed it! If you want something more complicated and real-world example, checkout how to split strings in bash using arrays.
And, of course, you may practice what you just learned by solving the problems and referring to their solutions if you get stuck or need a hint.
In the next chapter, I will show you how to use various bash arithmetic operators.