Bash Arrays Reference
Indexed Arrays
# Declare and initialize
fruits=("apple" "banana" "cherry")
declare -a servers=("web1" "web2" "db1")
servers[3]="db2" # add by index
# Access elements
echo "${fruits[0]}" # apple
echo "${fruits[-1]}" # cherry (last element)
echo "${fruits[@]}" # all elements
echo "${fruits[*]}" # all elements (as single string when quoted)
echo "${#fruits[@]}" # count: 3
echo "${!fruits[@]}" # indices: 0 1 2
# Append element
fruits+=("date")
fruits[${#fruits[@]}]="elderberry"
# Remove element (leaves gap)
unset fruits[1] # removes "banana"
fruits=("${fruits[@]}") # re-index after removal
# Slice: ${array[@]:start:length}
echo "${fruits[@]:1:2}" # elements from index 1, length 2
# Merge arrays
all=("${fruits[@]}" "${servers[@]}")
Associative Arrays (dictionaries)
# Declare associative array (bash 4+)
declare -A config
config["host"]="db.example.com"
config["port"]="5432"
config["database"]="myapp"
# Inline declaration
declare -A colors=(
["red"]="#FF0000"
["green"]="#00FF00"
["blue"]="#0000FF"
)
# Access values
echo "${config["host"]}" # db.example.com
echo "${config[port]}" # 5432
# Get all keys and values
echo "${!config[@]}" # keys
echo "${config[@]}" # values
# Check if key exists
if [[ -v config["host"] ]]; then
echo "host is set"
fi
# Iterate
for key in "${!config[@]}"; do
echo "$key = ${config[$key]}"
done
# Delete key
unset config["port"]
Array Iteration Patterns
# Basic iteration
servers=("web1" "web2" "db1" "db2")
for server in "${servers[@]}"; do
echo "Pinging $server"
ping -c 1 "$server" &>/dev/null && echo "OK" || echo "FAILED"
done
# Iterate with index
for i in "${!servers[@]}"; do
echo "[$i] ${servers[$i]}"
done
# Iterate pairs from parallel arrays
names=("alice" "bob" "charlie")
roles=("admin" "developer" "viewer")
for i in "${!names[@]}"; do
echo "${names[$i]} has role ${roles[$i]}"
done
# Read array from file
mapfile -t lines < /etc/hosts # bash 4+
readarray -t lines < /etc/hosts # equivalent
# Read array from command output
mapfile -t processes < <(ps aux | awk '{print $1}')
for proc in "${processes[@]}"; do
echo "$proc"
done
Array Operations
# Search / contains
contains() {
local needle="$1"; shift
for item in "$@"; do
[[ "$item" == "$needle" ]] && return 0
done
return 1
}
fruits=("apple" "banana" "cherry")
if contains "banana" "${fruits[@]}"; then
echo "found"
fi
# Join array with separator
join_by() {
local sep="$1"; shift
local result="$1"; shift
for item in "$@"; do
result="${result}${sep}${item}"
done
echo "$result"
}
echo "$(join_by , "${fruits[@]}")" # apple,banana,cherry
# Unique values (sort + uniq)
arr=("a" "b" "a" "c" "b")
unique=($(printf '%s\n' "${arr[@]}" | sort -u))
# Reverse array
reversed=()
for (( i=${#fruits[@]}-1; i>=0; i-- )); do
reversed+=("${fruits[$i]}")
done
Map & Filter Patterns
# Map: transform each element
numbers=(1 2 3 4 5)
doubled=()
for n in "${numbers[@]}"; do
doubled+=("$((n * 2))")
done
echo "${doubled[@]}" # 2 4 6 8 10
# Filter: keep elements matching condition
evens=()
for n in "${numbers[@]}"; do
(( n % 2 == 0 )) && evens+=("$n")
done
echo "${evens[@]}" # 2 4
# Map with string transformation
files=("app.js" "index.js" "utils.js")
paths=()
for f in "${files[@]}"; do
paths+=("/opt/myapp/src/${f}")
done
# Find + mapfile pattern
mapfile -t large_files < <(find /var/log -name "*.log" -size +10M)
echo "Large log files: ${#large_files[@]}"