2

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
!
  • 3
    Does adding -t to readarray help? – Jeff Schaller Apr 5 '17 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. – dave_thompson_085 Apr 5 '17 at 4:05
3

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.

  • "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 at 13:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.