Bash Arrays
Storing and managing multiple values efficiently
📚 What are Bash Arrays?
Arrays store multiple values in a single variable, like a list of items. They help organize related data together and make it easy to process collections of values using loops and other operations.
#!/bin/bash
# Simple array
fruits=("Apple" "Banana" "Orange")
echo "First fruit: ${fruits[0]}"
echo "All fruits: ${fruits[@]}"
Output:
First fruit: Apple All fruits: Apple Banana Orange
Array Operations
Create
Initialize arrays
arr=("a" "b" "c")
Access
Get array elements
echo ${arr[0]}
Modify
Update array values
arr[0]="new value"
Iterate
Loop through arrays
for item in "${arr[@]}"
🔹 Creating Arrays
Arrays in Bash store ordered collections of data, created by listing elements inside parentheses. Syntax: fruits=("apple" "banana" "cherry"). You can create an empty array with declare -a arr or build one dynamically by appending (arr+=("new")). Arrays are zero-indexed. Use ${array[@]} to expand all elements (properly quoted) or ${array[*]} to expand as a single string.
#!/bin/bash
# Create array with values
colors=("Red" "Green" "Blue" "Yellow")
echo "Colors: ${colors[@]}"
# Create empty array and add elements
numbers=()
numbers[0]=10
numbers[1]=20
numbers[2]=30
echo "Numbers: ${numbers[@]}"
# Create array from command output
files=($(ls *.txt))
echo "Text files: ${files[@]}"
# Create array with range
sequence=({1..5})
echo "Sequence: ${sequence[@]}"
# Declare array explicitly
declare -a names
names=("Alice" "Bob" "Charlie")
echo "Names: ${names[@]}"
Output:
Colors: Red Green Blue Yellow Numbers: 10 20 30 Text files: data.txt notes.txt readme.txt Sequence: 1 2 3 4 5 Names: Alice Bob Charlie
🔹 Accessing Array Elements
Access array elements individually using their numeric index inside square brackets and curly braces. For example, ${fruits[0]} gets the first element "apple". ${#fruits[@]} returns the number of elements. Use ${!fruits[@]} to get a list of all indices. This syntax allows precise retrieval and measurement of array data, which is fundamental for any script that processes lists of items like filenames, usernames, or configuration values.
#!/bin/bash
# Create array
fruits=("Apple" "Banana" "Orange" "Grape" "Mango")
# Access individual elements
echo "First fruit: ${fruits[0]}"
echo "Second fruit: ${fruits[1]}"
echo "Last fruit: ${fruits[4]}"
# Access all elements
echo "All fruits: ${fruits[@]}"
echo "All fruits (alternative): ${fruits[*]}"
# Get array length
echo "Number of fruits: ${#fruits[@]}"
# Get length of specific element
echo "Length of first fruit: ${#fruits[0]}"
# Access range of elements (using array slice)
echo "First three: ${fruits[@]:0:3}"
# Get all indices
echo "Indices: ${!fruits[@]}"
Output:
First fruit: Apple Second fruit: Banana Last fruit: Mango All fruits: Apple Banana Orange Grape Mango All fruits (alternative): Apple Banana Orange Grape Mango Number of fruits: 5 Length of first fruit: 5 First three: Apple Banana Orange Indices: 0 1 2 3 4
🔹 Modifying Arrays
Arrays are mutable; you can update, add, or remove elements dynamically. Change an element: fruits[1]="blueberry". Append: fruits+=("date"). Remove: unset fruits[2] (note this leaves a gap; indices don't renumber). You can also merge arrays: arr3=("${arr1[@]}" "${arr2[@]}"). This flexibility lets arrays adapt to changing data needs within your script's logic.
#!/bin/bash
# Initial array
numbers=(10 20 30 40 50)
echo "Original: ${numbers[@]}"
# Update element
numbers[2]=35
echo "After update: ${numbers[@]}"
# Add element at end
numbers+=(60)
echo "After adding: ${numbers[@]}"
# Add multiple elements
numbers+=(70 80 90)
echo "After adding more: ${numbers[@]}"
# Remove element
unset numbers[3]
echo "After removing index 3: ${numbers[@]}"
# Replace element
numbers[0]=15
echo "After replacing first: ${numbers[@]}"
# Clear entire array
unset numbers
echo "After clearing: ${numbers[@]}"
# Recreate array
numbers=(1 2 3 4 5)
echo "New array: ${numbers[@]}"
Output:
Original: 10 20 30 40 50 After update: 10 20 35 40 50 After adding: 10 20 35 40 50 60 After adding more: 10 20 35 40 50 60 70 80 90 After removing index 3: 10 20 35 50 60 70 80 90 After replacing first: 15 20 35 50 60 70 80 90 After clearing: New array: 1 2 3 4 5
🔹 Looping Through Arrays
Iterating over arrays is typically done with a for loop. The safest method is for item in "${array[@]}"; do ... done, which handles each element individually, even if they contain spaces. To loop over indices, use for i in "${!array[@]}"; do echo "${array[$i]}"; done. This allows you to process, transform, or validate each piece of data in the collection, which is essential for batch operations and data manipulation tasks.
#!/bin/bash
# Array of names
names=("Alice" "Bob" "Charlie" "David" "Eve")
# Loop through elements
echo "Greeting everyone:"
for name in "${names[@]}"
do
echo "Hello, $name!"
done
# Loop with index
echo -e "\nNumbered list:"
for i in "${!names[@]}"
do
echo "$((i+1)). ${names[i]}"
done
# Array of numbers - calculate sum
numbers=(5 10 15 20 25)
sum=0
echo -e "\nCalculating sum:"
for num in "${numbers[@]}"
do
sum=$((sum + num))
echo "Adding $num, sum = $sum"
done
echo "Total: $sum"
# Filter array elements
echo -e "\nLong names (>4 chars):"
for name in "${names[@]}"
do
if [ ${#name} -gt 4 ]; then
echo " $name"
fi
done
Output:
Greeting everyone: Hello, Alice! Hello, Bob! Hello, Charlie! Hello, David! Hello, Eve! Numbered list: 1. Alice 2. Bob 3. Charlie 4. David 5. Eve Calculating sum: Adding 5, sum = 5 Adding 10, sum = 15 Adding 15, sum = 30 Adding 20, sum = 50 Adding 25, sum = 75 Total: 75 Long names (>4 chars): Alice Charlie David
🔹 Array Slicing and Manipulation
Extract sub-arrays using slice notation: ${array[@]:start:length}. For example, ${fruits[@]:1:2} gets two elements starting at index 1. You can copy an entire array with copy=("${original[@]}"). While Bash doesn't have built-in functions to reverse or sort arrays directly, slicing and loops can be combined to achieve these manipulations, allowing you to work with specific data segments efficiently.
#!/bin/bash
# Original array
letters=("A" "B" "C" "D" "E" "F" "G" "H")
echo "Original: ${letters[@]}"
# Get slice (start at index 2, take 3 elements)
slice1="${letters[@]:2:3}"
echo "Slice [2:3]: $slice1"
# Get slice from start
slice2="${letters[@]:0:4}"
echo "First 4: $slice2"
# Get slice to end
slice3="${letters[@]:5}"
echo "From index 5: $slice3"
# Copy array
copy=("${letters[@]}")
echo "Copy: ${copy[@]}"
# Concatenate arrays
arr1=(1 2 3)
arr2=(4 5 6)
combined=("${arr1[@]}" "${arr2[@]}")
echo "Combined: ${combined[@]}"
# Search in array
search="D"
for item in "${letters[@]}"
do
if [ "$item" = "$search" ]; then
echo "Found: $search"
break
fi
done
Output:
Original: A B C D E F G H Slice [2:3]: C D E First 4: A B C D From index 5: F G H Copy: A B C D E F G H Combined: 1 2 3 4 5 6 Found: D
🔹 Associative Arrays (Bash 4+)
Associative arrays (hashes/dictionaries) use string keys instead of numeric indices, declared with declare -A. Example: declare -A user; user["name"]="Alice"; user["id"]="100". Access values with ${user["name"]}. They are ideal for storing configuration key-value pairs, counting occurrences, or creating lookup tables. Iterate over keys with for key in "${!user[@]}"; do ... done.
#!/bin/bash
# Declare associative array
declare -A person
# Add key-value pairs
person[name]="John Doe"
person[age]=30
person[city]="New York"
person[job]="Developer"
# Access values
echo "Name: ${person[name]}"
echo "Age: ${person[age]}"
echo "City: ${person[city]}"
# Get all keys
echo -e "\nAll keys:"
for key in "${!person[@]}"
do
echo " $key"
done
# Get all values
echo -e "\nAll values:"
for value in "${person[@]}"
do
echo " $value"
done
# Key-value pairs
echo -e "\nComplete info:"
for key in "${!person[@]}"
do
echo " $key: ${person[$key]}"
done
# Check if key exists
if [ -n "${person[email]}" ]; then
echo "Email exists"
else
echo "Email not set"
fi
Output:
Name: John Doe Age: 30 City: New York All keys: name age city job All values: John Doe 30 New York Developer Complete info: name: John Doe age: 30 city: New York job: Developer Email not set