24

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
2
  • BTW, does anybody know how to fix SE's terrible formatting of the code above? Commented Jul 31, 2012 at 17:51
  • The "terrible formatting" is due to the apostrophes being interpreted as single quotes (which it expects to be balanced). Use the "block quote" tags instead of "code" tags. Commented Jul 31, 2012 at 17:59

2 Answers 2

41

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"
Sign up to request clarification or add additional context in comments.

1 Comment

yeah for mapfile oneliner :)
17

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"

2 Comments

Indeed, and -d option seems crucial to make it work
One caveat I did not know about when I posted this: the exit status will be non-zero, since a here string will never end with a null character like read -d '' will expect.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.