Skip to content

Latest commit

 

History

History
229 lines (173 loc) · 5.35 KB

File metadata and controls

229 lines (173 loc) · 5.35 KB

04. Arrays and String Operations

Status Module Bash

📚 Indexed Arrays

Bash arrays are zero-indexed. Unlike many languages, array elements can contain any string, including those with spaces.

# Declaration
fruits=("apple" "banana" "cherry" "date")

# Access elements
echo "${fruits[0]}"       # apple
echo "${fruits[2]}"       # cherry
echo "${fruits[-1]}"      # date (last element — Bash 4.2+)

# All elements (quote both ways work slightly differently)
echo "${fruits[@]}"       # apple banana cherry date
echo "${fruits[*]}"       # apple banana cherry date

# Number of elements
echo "${#fruits[@]}"      # 4

# Array slice (offset, length)
echo "${fruits[@]:1:2}"   # banana cherry (start at index 1, take 2)

# All indices
echo "${!fruits[@]}"      # 0 1 2 3

Modifying Arrays

# Append an element
fruits+=("elderberry")
fruits[5]="fig"

# Delete an element (the index gap remains)
unset fruits[1]
echo "${fruits[@]}"    # apple cherry date elderberry fig

# Re-index after deletion
fruits=("${fruits[@]}")   # Re-pack into a contiguous array

# Delete the entire array
unset fruits

Iterating

# Iterate over elements (always quote "$@" style)
for fruit in "${fruits[@]}"; do
    echo "Fruit: $fruit"
done

# Iterate with index
for i in "${!fruits[@]}"; do
    echo "fruits[$i] = ${fruits[$i]}"
done

🗺️ Associative Arrays (Dictionaries)

Bash 4.0+ supports key-value associative arrays. Declare them with -A:

# Declaration (requires Bash 4+)
declare -A config

# Assign key-value pairs
config[host]="localhost"
config[port]="5432"
config[database]="mydb"
config[user]="admin"

# Or declare and populate at once
declare -A http_codes=(
    [200]="OK"
    [301]="Moved Permanently"
    [404]="Not Found"
    [500]="Internal Server Error"
)

# Access by key
echo "${config[host]}"         # localhost
echo "${http_codes[404]}"      # Not Found

# All keys
echo "${!config[@]}"           # host port database user

# All values
echo "${config[@]}"            # localhost 5432 mydb admin

# Check if key exists
[[ -v config[host] ]] && echo "host key exists"

# Iterate key-value pairs
for key in "${!config[@]}"; do
    printf "  %-12s = %s\n" "$key" "${config[$key]}"
done

✂️ String Operations

Bash has powerful built-in string manipulation — no awk or sed needed for simple operations.

Length

str="Hello, World!"
echo "${#str}"      # 13

Substring Extraction

str="Hello, World!"
echo "${str:7}"        # World! (from index 7 to end)
echo "${str:7:5}"      # World (from index 7, length 5)
echo "${str: -6}"      # orld! (last 6 chars — note the space before -)

Substitution

path="/usr/local/bin/script.sh"

# Replace first match
echo "${path/local/global}"       # /usr/global/bin/script.sh

# Replace ALL matches
text="the cat sat on the mat"
echo "${text//the/a}"             # a cat sat on a mat

# Delete pattern (replace with nothing)
echo "${path//.sh/}"              # /usr/local/bin/script

Case Modification (Bash 4+)

str="Hello World"
echo "${str^^}"     # HELLO WORLD (all uppercase)
echo "${str,,}"     # hello world (all lowercase)
echo "${str^}"      # Hello World (capitalize first char)
echo "${str,}"      # hello World (lowercase first char)

Prefix and Suffix Stripping

filename="report_2026_final.tar.gz"

# Strip shortest prefix matching pattern (#)
echo "${filename#*_}"      # 2026_final.tar.gz

# Strip longest prefix matching pattern (##)
echo "${filename##*_}"     # final.tar.gz

# Strip shortest suffix matching pattern (%)
echo "${filename%.*}"      # report_2026_final.tar

# Strip longest suffix matching pattern (%%)
echo "${filename%%.*}"     # report_2026_final

# Practical: get filename without extension
file="archive.tar.gz"
base="${file%%.*}"         # archive
ext="${file#*.}"           # tar.gz

🔀 IFS — Internal Field Separator

IFS controls how Bash splits words. Temporarily changing it lets you split strings on custom delimiters:

# Split a CSV line into an array
IFS=',' read -ra fields <<< "alice,30,engineer,london"
echo "${fields[0]}"   # alice
echo "${fields[2]}"   # engineer

# Join array elements with a custom separator
arr=("apple" "banana" "cherry")
(IFS=','; echo "${arr[*]}")   # apple,banana,cherry

🏆 Summary

Indexed Arrays

arr=(a b c)           # Create
echo "${arr[0]}"      # Access
echo "${#arr[@]}"     # Length
arr+=(d)              # Append
for x in "${arr[@]}"; do ...; done   # Iterate

Associative Arrays

declare -A map
map[key]="value"      # Set
echo "${map[key]}"    # Get
echo "${!map[@]}"     # All keys

String Operations

${#str}          # Length
${str:N:L}       # Substring
${str/old/new}   # Replace first
${str//old/new}  # Replace all
${str^^}         # Uppercase
${str,,}         # Lowercase
${str#prefix}    # Strip prefix (shortest)
${str%suffix}    # Strip suffix (shortest)

👉 Next: Script Security Best Practices