Arrays
- Arrays
What is an array?
An array in Bash is a data structure that can store multiple values in a single variable. There are two types of arrays in bash:
- Indexed arrays: this type uses numeric indenes starting at 0
- Associative Arrays: this type uses keys (like a dictionary)
Declaring an array
Method 1: Using Parenthesis
The formula is simple: array name
+=
+(
+elements separated by a space
+)
. Example:
#!/bin/bash
# Array declaration example
users=("john" "Mary" "Peter" "Ivan")
This method is used for creating indexed arrays. It cannot be used to create associative arrays.
Method 2: Using declare command
The declare command is used to create and modify variables. It allows to control the scope of the variables as well. In the case of arrays, we can use to create indexed arrays or associative arrays. The syntax is: declare
+options
+array_name
+=
+value
Example:
#!/bin/bash
# Indexed array
declare -a users=("john" "peter" "joe")
# Accessing values
echo ${users[0]}1
#!/bin/bash
declare -A user
# Assign values
user["name"]="Alice"
user["age"]=35
user["eyes"]="brown"
user["city"]="New York"
user["email"]="alice_88@email.com"
user["username"]="a_wa339"
# accessing values:
echo -e ${user["name"]} lives in ${user["city"]}. She is ${user["age"]} years old \
her eyes color is ${user["eyes"]}. Her email address is ${user["email"]}.
Accessing elements of an array
The formula to access the an element of an array is as follows:
$
+{
+name_of_array
+[
+index
+]
+}
Examples
#!/bin/bash
users=("john" "peter" "mario")
echo ${users[0]} # outputs john
echo ${users[*]} # outputs all elements
echo ${users[@]} # outputs all elements
echo ${#users[@]} # Array length
echo ${users[-1]} # Last element
Modifying an array
- To add an element to the end of an array:
array_name+=(element)
- Example:
users+=("fred")
- To update a given element:
array_name[index_here]="element"
- Example:
users[0]="root"
- To remove an element:
unset array_name[index_to_delete]
- Example:
unset users[-1]
- To clear an entire array:
unset array_name
- Example:
unset users
#!/bin/bash
users=("john" "peter" "mario")
echo -e "Current size:\t${#users[*]}"
echo -e "Adding a new element: fred"
users+=("fred") #adding element
echo -e "New size:\t${#users[*]}"
echo -e "All elements\t${users[*]}"
echo -e "Updating first element to root"
users[0]="root" # updating first element
echo "All element: ${users[*]}"
echo "Removing last element"
unset users[-1] # removing last element
echo "All elements: ${users[*]}"
echo "Clearing array"
unset users
echo "All elements: ${users[*]}"
Looping through an array
Using for
Example:
#!/bin/bash
users=("john" "peter" "mario")
for user in "${users[*]}"
do
echo "Current user: $user"
done
# Example using indexes:
for i in "${!users[@]}"
do
echo "User $i => ${users[$i]}"
done
Interesting example:
Create a script that will get an array of all the users in a system then display each user name
#!/bin/bash
users=($(awk -F":" '{print $1}' /etc/passwd | tr '\n' " "))
for user in "${users[@]}"
do
echo "User: $user"
done
Using while
Example:
#!/bin/bash
users=("john" "peter" "mario")
index=0
while [[ $index -lt ${#users[@]} ]]
do
echo "User $index => ${users[$index]}"
((index++))
done
- This loop runs until the index is less than the length of the array
Using until
#!/bin/bash
users=("john" "peter" "mario")
index=0
until [[ $index -ge ${#users[@]} ]]
do
echo "User $index => ${users[$index]}"
((index++))
done
- The until loop continues until the condition becomes true. The opposite of a while loop.
Interesting Example
- You can use until and arrays to validate user input when the input is predictable.
- For example, you need the user to answer in one of the following forms: y Y Yes YES No NO n
#!/bin/bash
valid=("y" "Y" "YES" "Yes" "yes" "n" "N" "no" "No" "NO")
input=""
until [[ "${valid[@]}" =~ "$input" ]]
do
read -p "Continue? (y/n) " input
done
echo "The answer is correct: $input"
Working with associative arrays
Create an associative array:
Associative arrays use key value pairs to store date. For instance, you can have an array of values that stores the user’s name and their corresponding ip address.
Example:
#!/bin/bash
declare -A users
players=([bob]="192.168.1.16" [mary]="192.168.1.17" [joe]="192.168.1.18")
echo "${players[bob]}"
Accessing values
declare -A users
users=([bob]="192.168.1.16" [mary]="192.168.1.17" [joe]="192.168.1.18")
echo "${users[bob]}"
## Looping through keys
for key in "${!users[@]}"
do
echo "$key's ip is: ${users[$key]}"
done
Array operations
#!/bin/bash
users=($(awk -F":" '{print $1}' /etc/passwd | tr '\n' " "))
# Slicing
echo "${users[@]:1:2}" # Start at index 1, take 2 elements
# Sorting
sortedUsers=($(printf "%s\n" "${users[@]}" | sort))
echo "${sortedUsers[@]}"
# Searching for a given element
search_string=$(echo $USER)
for item in "${sortedUsers[@]}"
do
if [ "$item" == "$search_string" ]
then
echo "array contains $search_string"
if
done
## passing an array to a function
print_users(){
local array=("$@")
for item in "${array[@]}"
do
echo "$item"
done
}
print_users "${sorted_users[@]}"
## Reading an array from a file
mapfile -t my_array < file.txt
echo "${my_array[@]}"