keepcalculator

06 Numbers and Powers

Bash Array Operations: A Practical Guide

Card No. 06·55391 · Updated · Standard formula, shown below

Average pace 5.00 min/km
Average speed
12.00 km/h
Result
Finish time
50 min
You entered
Distance
10 km
You entered
You enter
Finish time, Distance
You get
Average pace, Average speed
Rounding
2 dp

Bash arrays let you store multiple values in one variable and manipulate them with built-in operations. This guide explains how to create, access, modify, and iterate over arrays in Bash, covering indexed and associative arrays, common pitfalls, and practical examples.

Formula

The calculator computes average pace and speed from a finish time and distance:

  • Pace (min/km) = Finish time (minutes) ÷ Distance (km)
  • Speed (km/h) = Distance (km) ÷ (Finish time (minutes) ÷ 60)

Variables: t = finish time in minutes, d = distance in kilometers. Pace is minutes per kilometer, speed is kilometers per hour.

Worked Example

Using the default values: t = 50 minutes, d = 10 km.

  1. Pace = 50 ÷ 10 = 5.00 min/km
  2. Speed = 10 ÷ (50 ÷ 60) = 10 ÷ 0.8333 = 12.00 km/h

The calculator shows 5.00 min/km and 12.00 km/h.

What Are Bash Arrays?

Bash arrays are variables that hold multiple items under one name. Unlike simple variables (e.g., name=Alice), an array like names=(Alice Bob Carol) stores three separate strings. You can access each element by its index (starting at 0), loop over all elements, add or remove items, and even use associative arrays (key-value pairs) in Bash 4.0 and later.

Arrays are essential for scripting tasks like processing file lists, parsing command output, or managing configuration values. They save you from creating dozens of separate variables and make your scripts cleaner and more maintainable.

Creating and Accessing Arrays

There are several ways to create an array in Bash:

  • Direct assignment: arr=(one two three)
  • With indices: arr[0]=one; arr[1]=two
  • From command output: arr=($(ls)) (splits on whitespace)
  • From a string: IFS=',' read -ra arr <<< "a,b,c"

Access elements with ${arr[0]} (first element), ${arr[@]} (all elements as separate words), and ${#arr[@]} (number of elements). To get all indices, use ${!arr[@]}.

Example:

fruits=(apple banana cherry)
echo ${fruits[1]}   # banana
echo ${#fruits[@]}  # 3
for f in "${fruits[@]}"; do echo $f; done

Always quote "${arr[@]}" to preserve elements with spaces.

Modifying Arrays

You can change, add, or remove elements:

  • Change an element: arr[0]=newvalue
  • Append: arr+=(newitem)
  • Remove an element: unset arr[1] (leaves a gap)
  • Remove entire array: unset arr
  • Slice a range: ${arr[@]:1:2} (elements 1 and 2)

To remove an element and reindex, you need to rebuild the array:

arr=(a b c d)
unset arr[1]
arr=("${arr[@]}")
echo ${arr[@]}  # a c d

Be careful: unset arr[1] leaves an empty slot, and ${#arr[@]} still counts it.

Associative Arrays

Bash 4.0+ supports associative arrays (key-value pairs). Declare with declare -A:

declare -A colors
colors[red]="#FF0000"
colors[green]="#00FF00"
echo ${colors[red]}  # #FF0000
echo ${!colors[@]}   # red green

Associative arrays are handy for lookups, configuration maps, or counting occurrences. Iterate with for key in "${!colors[@]}". Note that order is not guaranteed.

Common Pitfalls and Mistakes

Beginners often trip on these:

  • Forgetting quotes: ${arr[@]} without quotes splits elements with spaces. Always use "${arr[@]}".
  • Using ${arr} instead of ${arr[0]}: ${arr} is the same as ${arr[0]}, but it's confusing.
  • Index gaps after unset: Rebuild the array to get contiguous indices.
  • Word splitting in command substitution: arr=($(command)) splits on spaces, newlines, and tabs. Use readarray or mapfile for lines.
  • Off-by-one errors: Indices start at 0, so the last element is ${arr[${#arr[@]}-1]}.

Another misconception: ${#arr} gives the length of the first element, not the array length. Use ${#arr[@]}.

Iterating Over Arrays

The most common loop is for:

for item in "${arr[@]}"; do
  echo "$item"
done

If you need the index, use:

for i in "${!arr[@]}"; do
  echo "$i: ${arr[$i]}"
done

For associative arrays, iterate keys and access values inside the loop. Avoid for item in ${arr[@]} without quotes—it breaks on spaces.

Alternatives to Arrays

Sometimes arrays aren't the best fit:

  • Simple variables: For a fixed, small number of values.
  • Positional parameters: $@ and $1, $2 are already an array-like list.
  • Text files: Use mapfile to read lines into an array, or process line-by-line with while read.
  • Other languages: If you need complex data structures, consider Python or awk.

For most shell scripting, arrays are the right tool. For heavy data processing, a dedicated language is often clearer.

Frequently Asked Questions

How do I get the length of an array in Bash?

Use ${#arr[@]} to get the number of elements. For example, arr=(a b c); echo ${#arr[@]} prints 3. Note that ${#arr} gives the length of the first element.

How can I check if an array contains a specific value?

Loop through the array and compare, or use a case statement. A common pattern: for item in "${arr[@]}"; do if [[ $item == "target" ]]; then echo found; fi; done. There's no built-in in_array.

What's the difference between ${arr[@]} and ${arr[*]}?

When quoted, "${arr[@]}" expands each element as a separate word, preserving spaces. "${arr[*]}" joins all elements into one word using the first character of IFS (usually a space). Use @ for looping.

How do I read a file into an array in Bash?

Use mapfile or readarray: mapfile -t arr < file.txt reads each line into an element, stripping newlines. The -t flag removes trailing newlines.

Can I have arrays with keys that are strings?

Yes, with associative arrays. Declare with declare -A arr, then assign like arr[key]=value. Access with ${arr[key]}. This requires Bash 4.0 or later.

Why does my array seem to have empty elements?

This often happens after using unset on an element, leaving a gap. Also, command substitution may produce empty strings if the output has blank lines. Rebuild the array with arr=("${arr[@]}") to remove gaps.

Related

Formula used
in t | Finish time | min | 50 | 0
in d | Distance | km | 10 | 0 | 100000
out pace | Average pace | min/km | t / d | 2
out speed | Average speed | km/h | d / (t / 60) | 2

Each line is one input (in, sel, list) or one result (out: label, unit, formula, decimals). How the calculators work

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.

More cards in this drawer

The whole Numbers and Powers drawer →