How to split a string into an array in Bash?

To split a string into an array in Bash, you can use the read command with the -a flag or manipulate the string using parameter expansion and the Internal Field Separator (IFS). Below are detailed methods and examples for different scenarios.

1. Splitting by Whitespace (Default)

By default, Bash splits strings into arrays based on whitespace (spaces, tabs, newlines).
Example:

#!/bin/bash
str="apple banana cherry"
read -ra arr <<< "$str"  # -ra: read into array

# Print all elements
echo "Array elements:"
for element in "${arr[@]}"; do
  echo "$element"
done

Output:

apple
banana
cherry

2. Splitting by Custom Delimiter (e.g., comma)

Use IFS to define a custom delimiter (e.g., ,) and split the string.

Example 1: Basic Split

#!/bin/bash
str="apple,banana,cherry"
IFS=',' read -ra arr <<< "$str"

echo "Array elements:"
printf "%s\n" "${arr[@]}"

Output:

apple
banana
cherry

Example 2: Handling Leading/Trailing Delimiters

If the string has leading/trailing delimiters, empty elements are created:

str=",apple,,banana,"
IFS=',' read -ra arr <<< "$str"

# Print elements with indices
for index in "${!arr[@]}"; do
  echo "arr[$index] = ${arr[index]}"
done

Output:

arr[0] = 
arr[1] = apple
arr[2] = 
arr[3] = banana
arr[4] = 

3. Splitting with Parameter Expansion

Use ${string//pattern/replacement} to replace delimiters with spaces and then create an array.

Example:

#!/bin/bash
str="apple:banana:cherry"
# Replace ':' with spaces and assign to array
arr=(${str//:/ })

echo "Array elements:"
echo "${arr[@]}"

Output:

apple banana cherry

Limitations:

  • Fails if elements contain spaces or special characters (e.g., str="apple:red banana:yellow" splits into 4 elements).

4. Splitting with tr Command

Use tr to replace delimiters with spaces and create an array.

Example:

#!/bin/bash
str="apple,banana,cherry"
# Replace commas with spaces and assign to array
arr=($(echo "$str" | tr ',' ' '))

echo "Array elements:"
echo "${arr[@]}"

Output:

apple banana cherry

Note:
Same limitations as parameter expansion (spaces in elements cause unintended splits).

5. Advanced Splitting with awk

Use awk for complex splitting (e.g., multiple delimiters or filtering).

Example: Split by Multiple Delimiters

#!/bin/bash
str="apple,banana;cherry|grape"
# Split using commas, semicolons, or pipes
arr=($(echo "$str" | awk 'BEGIN {FS="[,;|]"} {for (i=1; i<=NF; i++) print $i}'))

echo "Array elements:"
printf "%s\n" "${arr[@]}"

Output:

apple
banana
cherry
grape

6. Splitting Lines into Arrays

To split a multi-line string into an array (one line per element):

#!/bin/bash
str="Line 1
Line 2
Line 3"

# Read lines into array
mapfile -t arr <<< "$str"

echo "Array elements:"
printf "%s\n" "${arr[@]}"

Output:

Line 1
Line 2
Line 3

Key Notes

  1. IFS Behavior:
  • IFS resets to default after the command unless modified globally (use IFS=... before the command).
  • To preserve IFS, reset it after splitting:
    bash OLD_IFS="$IFS" IFS=',' read -ra arr <<< "$str" IFS="$OLD_IFS"
  1. Handling Empty Elements:
  • Use mapfile or read with IFS to retain empty elements.
  1. Quoting:
  • Always quote variables (e.g., "$str") to preserve spaces in elements.

Summary of Methods

MethodUse CasePitfalls
read -ra with IFSSimple splits with custom delimiters.Trims leading/trailing spaces.
Parameter ExpansionQuick splits without external commands.Fails with spaces in elements.
tr CommandReplace delimiters for simple splits.Same as parameter expansion.
awkComplex splits with multiple delimiters.Requires external command.
mapfileSplit multi-line strings into arrays.Bash 4.0+ only.

Full Example: Split and Process Elements

#!/bin/bash
str="apple, banana, cherry, date"

# Split into array and trim spaces
IFS=',' read -ra arr <<< "$str"
for i in "${!arr[@]}"; do
  arr[$i]=$(echo "${arr[$i]}" | xargs)  # Trim whitespace
done

echo "Trimmed elements:"
printf "'%s'\n" "${arr[@]}"

Output:

'apple'
'banana'
'cherry'
'date'

By choosing the appropriate method, you can split strings into arrays in Bash efficiently.

Leave a Reply

Your email address will not be published. Required fields are marked *