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
IFSBehavior:
IFSresets to default after the command unless modified globally (useIFS=...before the command).- To preserve
IFS, reset it after splitting:bash OLD_IFS="$IFS" IFS=',' read -ra arr <<< "$str" IFS="$OLD_IFS"
- Handling Empty Elements:
- Use
mapfileorreadwithIFSto retain empty elements.
- Quoting:
- Always quote variables (e.g.,
"$str") to preserve spaces in elements.
Summary of Methods
| Method | Use Case | Pitfalls |
|---|---|---|
read -ra with IFS | Simple splits with custom delimiters. | Trims leading/trailing spaces. |
| Parameter Expansion | Quick splits without external commands. | Fails with spaces in elements. |
tr Command | Replace delimiters for simple splits. | Same as parameter expansion. |
awk | Complex splits with multiple delimiters. | Requires external command. |
mapfile | Split 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.