4

I found a behavior of readarray that I can't get to the bottom of myself.

The following code:

readarray array < <(echo -e "Jenny\nJane\nJessica")

echo "* Not enclosed:"
for ((i=0; i<${#array[@]}; i++)); do
    echo ${array[$i]}
done

echo "* Enclosed:"
for ((i=0; i<${#array[@]}; i++)); do
    echo "${array[$i]}"
done

Produces the following output:

* Not enclosed:
Jenny
Jane
Jessica
* Enclosed:
Jenny

Jane

Jessica

Why exactly do elements become spaced out when they are enclosed with " " like this?
Even if I replaced echo "${array[$i]}" with a variable like this:

foo=${array[$i]}
echo "$foo"

The output still becomes spaced out.
But note that if I declared the array in the usual fashion array=("Jenny" "Jane "Jessica") no spacing is inserted regardless of quotes.

Reason why this is causing problems because I'm looping through an array and need to use the element inside a sentence and echo it. For example:

readarray array < <(echo -e "Jenny\nJane\nJessica")
for ((i=0; i<${#array[@]}; i++)); do
    echo "Hello, ${array[$i]}!"
done

However ${array[$i]} is in-between " " so \n gets inserted and the output becomes:

Hello, Jenny
!
Hello, Jane
!
Hello, Jessica
!
2
  • 4
    Does adding -t to readarray help?
    – Jeff Schaller
    Apr 5, 2017 at 1:35
  • 1
    In other words, there IS an entirely real newline in each array element value, but echo ${ary[sub]} or echo $var without quotes (and without fiddled IFS) removes any leading, trailing, or consecutive whitespace, regardless of where it came from. Apr 5, 2017 at 4:05

1 Answer 1

4

It is because the readarray doesn't remove the delimiter (newline by default) unless it is called with the -t option.

Using the simpler declare -p var to print array values, look at this:

$ readarray array < <(echo -e "Jenny\nJane\nJessica")
$ declare -p array
declare -a array=([0]=$'Jenny\n' [1]=$'Jane\n' [2]=$'Jessica\n')

You can see the trailing newlines for each element.

While this:

$ readarray -t array < <(echo -e "Jenny\nJane\nJessica")
$ declare -p array
declare -a array=([0]="Jenny" [1]="Jane" [2]="Jessica")

does not have trailing newlines.

The use of an unquoted variable expansion is just a bad idea, just don't.

1
  • "The use of an unquoted variable expansion is just a bad idea, just don't." Sure. But when using "=~" to match against a regular expression, quotes are forbidden on the regex (right hand) side of the operator. If you're reading an array of regexes from a file, you need this. I think. Unless I'm missing the obvious, which I usually do....
    – nclark
    Jul 1, 2019 at 13:42

You must log in to answer this question.

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