Friday, 30 June 2017

How to split a multi-line string containing the characters "n" into an array of strings in bash?





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

Answer



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"

No comments:

Post a Comment

casting - Why wasn&#39;t Tobey Maguire in The Amazing Spider-Man? - Movies &amp; TV

In the Spider-Man franchise, Tobey Maguire is an outstanding performer as a Spider-Man and also reprised his role in the sequels Spider-Man...