Reading a space-delimited string into an array in Bash
ArraysStringBashShellArrays Problem Overview
I have a variable which contains a space-delimited string:
line="1 1.50 string"
I want to split that string with space as a delimiter and store the result in an array, so that the following:
echo ${arr[0]}
echo ${arr[1]}
echo ${arr[2]}
outputs
1
1.50
string
Somewhere I found a solution which doesn't work:
arr=$(echo ${line})
If I run the echo statements above after this, I get:
1 1.50 string
[empty line]
[empty line]
I also tried
IFS=" "
arr=$(echo ${line})
with the same result. Can someone help, please?
Arrays Solutions
Solution 1 - Arrays
In order to convert a string into an array, create an array from the string, letting the string get split naturally according to the IFS
(Internal Field Separator) variable, which is the space char by default:
arr=($line)
or pass the string to the stdin of the read
command using the herestring (<<<
) operator:
read -a arr <<< "$line"
For the first example, it is crucial not to use quotes around $line
since that is what allows the string to get split into multiple elements.
See also: https://github.com/koalaman/shellcheck/wiki/SC2206
Solution 2 - Arrays
In: arr=( $line )
. The "split" comes associated with "glob".
Wildcards (*
,?
and []
) will be expanded to matching filenames.
The correct solution is only slightly more complex:
IFS=' ' read -a arr <<< "$line"
No globbing problem; the split character is set in $IFS
, variables quoted.
Solution 3 - Arrays
Try this:
arr=(`echo ${line}`);
Solution 4 - Arrays
If you need parameter expansion, then try:
eval "arr=($line)"
For example, take the following code.
line='a b "c d" "*" *'
eval "arr=($line)"
for s in "${arr[@]}"; do
echo "$s"
done
If the current directory contained the files a.txt
, b.txt
and c.txt
, then executing the code would produce the following output.
a
b
c d
*
a.txt
b.txt
c.txt
Solution 5 - Arrays
line="1 1.50 string"
arr=$( $line | tr " " "\n")
for x in $arr
do
echo "> [$x]"
done