Big Shield
Big Shield

Reputation: 622

What is the difference can be tested between mapfile and mapfile -t?

Sample 1 with option t:

f(){
        mapfile -t aaa < /dev/stdin
        echo -e ${aaa[@]}
}
echo -e "a\nb\nc" | f

Sample 2 without option t:

f(){
        mapfile aaa < /dev/stdin
        echo -e ${aaa[@]}
}
echo -e "a\nb\nc" | f

The outputs are same: a b c

EDIT:

Why are there two whitespaces in @cdarke's and @heemayl's answer?
echo -e "a\nb\nc" | f2 | od -b

0000000 141 012 040 142 012 040 143 012 012
0000011

Then I tried this: echo -e "a\tb\tc" | f2 | od -b

0000000 141 011 142 011 143 012 012
0000007

And there are no whitespaces.

Thx in advance!

Upvotes: 1

Views: 37

Answers (2)

heemayl
heemayl

Reputation: 42097

To see the difference quote ${aaa[@]}:

echo -e "${aaa[@]}"

Without quoting the expansion is being subjected to word splitting according to IFS (and pathname expansion too). As the elements (strings) contain newlines, these will go through word splitting.

Example:

$ f() { mapfile -t aaa < /dev/stdin; echo -e "${aaa[@]}" ;}
$ echo -e "a\nb\nc" | f
a b c

$ g() { mapfile aaa < /dev/stdin; echo -e "${aaa[@]}" ;}
$ echo -e "a\nb\nc" | g
a
 b
 c

Upvotes: 2

cdarke
cdarke

Reputation: 44394

The problem is with the echo:

f1(){
    mapfile -t aaa < /dev/stdin
    echo -e "${aaa[@]}"       # note the quotes
}
echo -e "a\nb\nc" | f1

f2(){
    mapfile aaa < /dev/stdin
    echo -e "${aaa[@]}"       # note the quotes
}
echo -e "a\nb\nc" | f2

Gives:

a b c
a
 b
 c

In the second case, without the quotes, the newlines are seen as whitespace.

Upvotes: 1

Related Questions