1

this one has me baffled.

Here are 2 versions of loading a bash array, one works, the other does not.

If I explicitly initialize the array within the script, it works fine:

zz=( 1 26 32 54 71 13 30 43 52 73 7 23 42 57 61 15 27 35 56 66 5 20 36 51 68 )

#print in reverse
for i in {24..0}
do
        echo "zz[$i] is ${zz[$i]}"
done

Output as expected:

zz[24] is 68
zz[23] is 51
zz[22] is 36
zz[21] is 20
zz[20] is 5
zz[19] is 66
zz[18] is 56
zz[17] is 35
zz[16] is 27
zz[15] is 15
zz[14] is 61
zz[13] is 57
zz[12] is 42
zz[11] is 23
zz[10] is 7
zz[9] is 73
zz[8] is 52
zz[7] is 43
zz[6] is 30
zz[5] is 13
zz[4] is 71
zz[3] is 54
zz[2] is 32
zz[1] is 26
zz[0] is 1

This version does not work properly (at the moment):

# cat your_data
1 26 32 54 71 13 30 43 52 73 7 23 42 57 61 15 27 35 56 66 5 20 36 51 68
mapfile -t zz < your_data

#print in reverse
for i in {24..0}
do
        echo "zz[$i] is ${zz[$i]}"
done


Output:
zz[24] is
zz[23] is
zz[22] is
zz[21] is
zz[20] is
zz[19] is
zz[18] is
zz[17] is
zz[16] is
zz[15] is
zz[14] is
zz[13] is
zz[12] is
zz[11] is
zz[10] is
zz[9] is
zz[8] is
zz[7] is
zz[6] is
zz[5] is
zz[4] is
zz[3] is
zz[2] is
zz[1] is
zz[0] is 1 26 32 54 71 13 30 43 52 73 7 23 42 57 61 15 27 35 56 66 5 20 36 51 68

So when the data is read in via mapfile, it all gets stuffed in zz[0]. Even if I explicitly set IFS to space only (" "). I am pretty sure this was working at some point so maybe it is something in my environment. I am stumped...

Thanks, Snarksdad

2

The mapfile command reads the file line-wise, i.e. expects them separated by \n. Since you have the data space-separated, this (only) line in your file is taken as one single token and consequently assigned to the first array position. Try changing your input file as in

1
26
32

...

68

It should to the trick.

|improve this answer|||||
  • 1
    Or set a new delimiter with mapfile -d? – Kusalananda Dec 3 '19 at 15:46
  • Huh! I didn't know about that one. Can you point to documentation concerning this, none of the article I found mentioned it. – AdminBee Dec 3 '19 at 15:51
  • You'll get a newline in the last position of the array though... Maybe better to read it from tr ' ' '\n' or something? – Kusalananda Dec 3 '19 at 15:53
  • Thanks AdminBee, That does work though every thing I have read about mapfile led me to believe it would adhere to the IFS settings. – Snarksdad Dec 3 '19 at 16:07
  • 1
    It seems the -d option was introduced in bash version 4.4 – glenn jackman Dec 3 '19 at 17:27
1

If all your data is in one space-separated line in the file, do this:

read -r -a arrayname < filename

The -a is the key here: read a line from the file, split it according to $IFS, and store the fields in the array.

As has been pointed out, mapfile splits the file by lines not by words.

|improve this answer|||||

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.