1

I currently have a a bash variable that holds a string similar to this one,
where each different phrase is separated by a newline:

var="1st word
2nd word

4th word"

Note there is an empty space in between "2nd word" and "4th word".

I would like to place these phrases into an array as such, keeping the empty string in the 2nd index:
arr=("1st word" "2nd word" "" "4th word")

I tried the following code but it seems to ignore the empty space.
IFS=$'\n' read -rd '' -a arr <<<"$var"

Anyone happens to have a solution to this?

Thank you.

1 Answer 1

3

The issue with your approach is that it relies on word-splitting using an IFS whitespace character (i.e. newline). As noted in man bash:

                       Any  character  in IFS that is not IFS whitespace,
   along with any adjacent IFS whitespace characters, delimits a field.  A
   sequence  of  IFS whitespace characters is also treated as a delimiter.

So whatever options you pass to read, "$var" has already been split into 3 tokens, treating the adjacent newlines either side of the empty 3rd line as a single delimiter.

From bash version 4.0, you can instead use readarray (or its synonym, mapfile) to read whole lines:

$ var="1st word
2nd word

4th word"

$ readarray -t arr <<<"$var"

$ declare -p arr
declare -a arr=([0]="1st word" [1]="2nd word" [2]="" [3]="4th word")

If your bash is too old to provide readarray / mapfile, then you can do it with a loop:

$ arr=()
$ while IFS= read -r line; do arr+=("$line"); done <<<"$var"

$ declare -p arr
declare -a arr=([0]="1st word" [1]="2nd word" [2]="" [3]="4th word")
2
  • Is there an alternative way since readarray doesn't work on macOS?
    – lilek3
    Jul 29, 2021 at 1:12
  • @lilek3 please see updated answer Jul 29, 2021 at 2:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.