I have a string in the following format:
I'm\nNed\nNederlander
I'm\nLucky\nDay
I'm\nDusty\nBottoms
I would like to move this to an array of strings line by line such that:
$ echo "${ARRAY[0]}"
I'm\nNed\nNederlander
$ echo "${ARRAY[1]}"
I'm\nLucky\nDay
$ echo "${ARRAY[2]}"
I'm\nDusty\nBottoms
However, I'm running into problems with the "\n" characters within the string itself. They are represented in the string as two separate characters, the backslash and the 'n', but when I try to do the array split they get interpreted as newlines. Thus typical string splitting with IFS
does not work.
For example:
$ read -a ARRAY <<< "$STRING"
$ echo "${#ARRAY[@]}" # print number of elements
2
$ echo "${ARRAY[0]}"
I'mnNednNederla
$ echo "${ARRAY[1]}"
der
You can have a string split across multiple lines by enclosing it in triple quotes. Alternatively, brackets can also be used to spread a string into different lines. Moreover, backslash works as a line continuation character in Python. You can use it to join text on separate lines and create a multiline string.
To split long commands into readable commands that span multiple lines, we need to use the backslash character (\). The backslash character instructs bash to read the commands that follow line by line until it encounters an EOL.
By default, the read
builtin allows \ to escape characters. To turn off this behavior, use the -r
option. It is not often you will find a case where you do not want to use -r
.
string="I'm\nNed\nNederlander I'm\nLucky\nDay I'm\nDusty\nBottoms" arr=() while read -r line; do arr+=("$line") done <<< "$string"
In order to do this in one-line (like you were attempting with read -a
), actually requires mapfile
in bash v4 or higher:
mapfile -t arr <<< "$string"
mapfile
is more elegant, but it is possible to do this in one (ugly) line with read
(useful if you're using a version of bash older than 4):
IFS=$'\n' read -d '' -r -a arr <<< "$string"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With