1. Overview

Splitting a string into an array is a common task in computer programming. For example, we might want to extract words from lines within a text file or process user input in a certain way.

In this tutorial, we’ll learn techniques to convert a string to an array using the Bash shell.

2. Iterating Over a String

A for loop construct in Bash can split a string value and iterate over the tokens. The for loop performs string splitting based on the characters defined in the IFS shell variable.

2.1. Split a Sentence Into Words

To begin the process of splitting a sentence into words, let’s declare a shell variable and assign a sentence where words are separated with spaces:

$ sentence='Hello World of Linux'

In this example, we set the value of the shell variable named sentence to the string value ‘Hello World of Linux’. Furthermore, we placed the string inside single quotes to prevent the assignment from failing.

Next, let’s create an empty array where we’ll put the words of the sentence after splitting it:

$ words=()

Now, we’re ready to create the loop that splits the sentence and adds the words to the words array:

$ for i in $sentence; do words+=($i) ; done

Here, the loop extracts the next word from the sentence and assigns it to the i variable. Then, we use the += operator to add the value of the i variable to the words array.

Finally, let’s print the elements of the words array to verify the result of our script:

$ for word in ${words[@]}; do echo $word ; done
Hello
World
of
Linux

Indeed, the sentence was split into words and the words were added to the words array correctly.

2.2. Using Other Separator Characters

The for loop uses the characters in the IFS shell variable to split strings. IFS stands for Internal Field Separator and Bash uses it to recognize fields. Its value defaults to ” \t\n”, meaning that the shell uses the space, the tab, or the newline characters to split a string value into fields or words.

If we want to split a string using a different character, we can append the desired character to the IFS variable. For example, let’s change our sentence:

$ sentence='Hello#World#of#Linux'

As we can see, we’ve used the # character to separate words. Next, let’s add the # character to the IFS variable:

$ IFS=$IFS#
$ printf "%q" "$IFS"
$' \t\n#'

Indeed, we successfully appended the # character to the IFS variable. Furthermore, we used the printf “%q” command to print the value of the IFS variable. The %q format escapes non-printable characters. As a result, the space, tab, and newline characters are clearly printed on the terminal.

Next, let’s empty the words array and run for again:

$ words=()
$ for i in $sentence; do words+=($i) ; done
$ for word in ${words[@]}; do echo $word ; done
Hello
world
of
Linux

Indeed, we can see that the for construct used the # character as a field separator and split the sentence into words.

Finally, we can reset IFS to its initial value by removing the # character:

$ IFS="${IFS:0:3}"
$ printf '%q' "${IFS}"
' \t\n'

As we can see, we extracted a three-character length substring of IFS, starting from position 0, and assigned it back to the IFS variable.

3. Using the read Command

Another technique to split a string into an array is to use the read command with the -a option.

The read command’s purpose is to capture user input into shell variables. Similar to the for loop, it uses the characters in the IFS variable as field separators:

$ words=()
$ read -a words
Hello World of Linux
$ for word in ${words[@]}; do echo $word ; done
Hello
World
of
Linux

Here, the read command loads the words of the sentence to the words array because of the -a option. In particular, we specified the array variable after the -a option. Furthermore, the read command waits until we enter a string value.

Notably, entering the string value interactively isn’t very convenient. Instead, we can input a here-string to avoid the read command being blocked:

$ words=()
$ read -a words <<< "Hello World of Linux"
$ for word in ${words[@]}; do echo $word ; done
Hello
World
of
Linux

In this example, we used the <<< operator to input the here-string to the read command. This form is convenient when we want to split a string inside a shell script.

Moreover, we can again add separator characters to the IFS variable:

$ IFS=$IFS#
$ words=()
$ read -a words <<< "Hello#World#of#Linux"
$ for word in ${words[@]}; do echo $word ; done
Hello
World
of
Linux

As we can see, read was also successful in splitting a string into words that were separated by the # character, after appending this character to the IFS string.

4. Conclusion

In this article, we talked about splitting a string into an array in the Bash shell. We showcased two methods, the first using a for loop and the second using the read command.