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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .