11

I want to accomplish the equivalent of:

list=()
while read i; do
  list+=("$i")
done <<<"$input"

with

IFS=$'\n' read -r -a list <<<"$input"

What am I doing wrong?

input=`/bin/ls /`

IFS=$'\n' read -r -a list <<<"$input"

for i in "${list[@]}"; do
  echo "$i"
done

This should print a listing of /, but I'm only getting the first item.

1
  • 4
    If you are really trying to parse the output of ls, don't. Use list=(/*).
    – chepner
    Nov 23, 2015 at 14:50

3 Answers 3

16

You must use mapfile (or its synonym readarray, which was introduced in bash 4.0):

mapfile -t list <<<"$input"

One read invocation only work with one line, not the entire standard input.

read -a list populate the content of first line of standard in to the array list. In your case, you got bin as the only element in array `list.

2
  • 2
    @cuonglm The IFS is useless, because mapfile doesn't do any word-splitting on its input.
    – chepner
    Nov 23, 2015 at 14:47
  • @StéphaneChazelas: My bad, removed it.
    – cuonglm
    Nov 23, 2015 at 15:34
6

for bash versions that do not support mapfile

IFS=$'\n' read -ra list -d '' <<< "$input"

should do the trick

2
  • 3
    One minor drawback; this command will always have a non-zero exit status.
    – chepner
    Nov 23, 2015 at 14:46
  • 2
    Also note that it removes empty elements. Nov 23, 2015 at 16:47
5

Solution for Bash version 3 (and 4)

I happened to be logged in to a CentOS 5 box running Bash 3 and I had been working on a solution. I’ve already upvoted cuonglm’s answer but I thought I may as well post the solution I came up with that should work with Bash 3 (and 4). I’ve tested it with a file which had a space in its name and another which begins with -.

Instead of

IFS=$'\n' read -r -a list <<<"$input"

simply use command substitution to create and populate the array:

IFS=$'\n' # split on newline only
set -f    # disable globbing
list=($(printf "%s" "$input"))

Note: This won’t work with filenames which have newlines in their name.

0

You must log in to answer this question.

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