3

I'm using this code to load file into array in bash:

IFS=$'\n' read -d '' -r -a LINES < "$PAR1"

But unfortunately this code skips empty lines.

I tried the next code:

IFS=$'\n' read -r -a LINES < "$PAR1"

But this variant only loads one line.

How do I load file to array in bash, without skipping empty lines?

P.S. I check the number of loaded lines by the next command:

echo ${#LINES[@]}
Alex Tiger
  • 377
  • 3
  • 22
  • 1
    All-caps variable names are reserved by convention to avoid overwriting system-impacting names by mistake. See fourth paragraph of http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html, keeping in mind that environment variables and shell variables share a namespace. – Charles Duffy Aug 05 '15 at 23:01
  • See also: [Convert multiline string to array](https://stackoverflow.com/q/24628076/4561887). I've just updated [my answer here](https://stackoverflow.com/a/71575442/4561887) to highlight this important distinction between `read` and `mapfile`: `read` does _not_ keep empty elements in the array, but `mapfile` _does_. – Gabriel Staples Mar 28 '22 at 06:38

2 Answers2

3

You can use mapfile available in BASH 4+

mapfile -t lines < "$PAR1"
anubhava
  • 761,203
  • 64
  • 569
  • 643
2

To avoid doing anything fancy, and stay compatible with all versions of bash in common use (as of this writing, Apple is shipping bash 3.2.x to avoid needing to comply with the GPLv3):

lines=( )
while IFS= read -r line; do
  lines+=( "$line" )
done

See also BashFAQ #001.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • Great thanks! As for the last line I used the code from your link: `lines=( ) while IFS= read -r line do lines+=( "$line" ) done < "$PAR1" [[ -n $line ]] && lines+=( "$line" )` – Alex Tiger Aug 06 '15 at 08:35
  • Correct- the more complete answer (to fix skipping the last line) is to add `[[ -n $line ]] && lines+=( "$line" )` at the end. Learned this the hard way! – skupjoe May 11 '22 at 18:23
  • @skupjoe, or you can make it `while IFS= read -r line || [[ $line ]]; do`. You only need that if you use files made by someone who runs Windows (or tools that follow Microsoft's lead in considering newlines line _separators_ instead of _terminators_), though, so if you're a right-thinking person who uses UNIX and only uses files made by people who do likewise, it's completely unnecessary, right? :) – Charles Duffy May 11 '22 at 19:22
  • @CharlesDuffy Hmm, well, creating and using such a file that is only one entry long which is in LF format and doesn't end with a newline in VSCode (yes, from Windows machine) seems to exhibit this behavior when I then use this file in a Bash script that loads it to an array, executed from OSX, synced via Dropbox. Complicated, I know, but I dev cross-platform and from many different clients :D – skupjoe May 13 '22 at 06:42