1

my code:

#!/usr/bin/bash
        
IFS=$'\n'; read -r -a item < "animals.txt"
declare -p item

animals.txt:

dog
cat
duck
bird

desired output:

declare -a item=([0]="dog" [1]=" cat" [2]=" duck" [3]=" bird")

what I get:

declare -a item=([0]="dog")

The Bash documentation says that if IFS is unset, then the default value will be <space>, <tab> and <newline>, but even if I remove the IFS=$'\n' from the code, it still doesn't work.

  • 1
    With IFS set to either the default or to the string you are using, `read` will read one line from the input and split it into fields for the entries of the array. it does not read each line into a value of the array. Perhaps you want `read -a item <<< $(tr '\n' ' ' < animals.txt)`, but it depends on how you want to treat whitespace. – William Pursell May 31 '22 at 01:50
  • Or perhaps you want something like: `item=(); while read k; do item+=($k); done < animals.txt` – William Pursell May 31 '22 at 01:51
  • Or just remove the `;` – Jetchisel May 31 '22 at 02:37

1 Answers1

2
  1. read (including read -a) reads 1 line of input, splitting on white space by default (controlled by the IFS setting).
  2. readarray (aka mapfile) reads multiple lines of input, splitting on newlines by default (controlled by its -d argument).
$ readarray -t item < animals.txt
$ declare -p item
declare -a item=([0]="dog" [1]="cat" [2]="duck" [3]="bird")
Ed Morton
  • 188,023
  • 17
  • 78
  • 185