0

I've read several articles that talk about how to populate a Bash array where each entry has spaces in it. I believe I've gotten that working.

What I need to do is do this in a loop, populating a larger array with the contents of all the arrays in each iteration.

So, I have an outer loop iterating through the entries of an array that I got from another script. In each iteration of that loop, I run a command line that produces several lines of output, and I want each line to be an array entry. I have to add all of those array entries to the "summary" array. As I'm not aware of a way to just "append the contents of this array to another array", I assume I have to iterate through the smaller array. Up to now, this is doing what I need. However, the append to the larger array doesn't appear to be working correctly. After I do that append to the larger array and check the length of the larger array, it is always just "1".

The relevant part of the script is approximately this:

nslist=$(...)
pnarray=()
for ns in $nslist; do
    IFS=$'\n' nspnarray=($(...))
    echo "nspnarray.len[${#nspnarray[@]}]" # This looks fine
    for pn in ${nspnarray[@]}; do
        echo "pn[$pn]" # This looks fine
        IFS=$'\n' pnarray+=$pn # Something wrong with this?
        echo "pnarray.len[${#pnarray[@]}]" # is always 1
    done
done

This isn't a complete script, so I hope this is clear. The lines with "This looks fine" comments print out what I want. In my sample data, the command line that I call in the "nspnarray" assignment produces five lines of output, and the "nspnarray.len" print statement shows "5".

I then iterate through each of the five entries, printing each one. This still looks fine. It prints a value with spaces in it, as expected. I then try to assign that to my "summary" array, and then I print the length of the summary array, which always prints "1". I assume I'm doing something wrong in the assignment on the "Something wrong with this?" line.

1 Answer 1

0

Adding an array to another array is pretty straight-forward:

$ a=(1 2 3)
$ b=(4 5 6)
$ a+=("${b[@]}")
$ typeset -p a
declare -a a=([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6")

If you're doing relatively complicated things with arrays, though, you really should use a language more suited to the task. awk or perl, for example. Or python. Or pretty much anything except bash or other shells.

A shell is good for orchestrating the execution of other programs (and pipelines of other programs, and redirection of stdin and stdout, etc) to do things or to process data. It is not good at doing those other tasks itself - in fact, it is terrible at it.

awk has multi-dimensional arrays (both indexed and associative), perl does too and also has data structures where arrays or hashes can contain other arrays and/or hashes, nested arbitrarily deep. Most other languages also have complex data structures.

And, just as importantly, they don't have the quoting or word-splitting issues that shells do.

6
  • Think I'd be asking this question if I didn't wholeheartedly believe that? :) Jun 21, 2021 at 23:20
  • believe what? that it's simple to add two arrays in bash? or that you should use any language that isn't a shell?
    – cas
    Jun 21, 2021 at 23:21
  • I was referring to your last few paragraphs, pointing out that I probably shouldn't be doing this in bash. Jun 21, 2021 at 23:30
  • Now to the content of your answer, I'm a little confused by the last two lines of your code sample. It appears you said to type "typeset -p a". From what I can tell, there is no "-p" option for "typeset". I would think it is "-a", not "-p". Curiously, if I change it to "-a", it makes my sample break. I'll have to update the main post with details. Jun 21, 2021 at 23:32
  • 1
    @DavidM.Karr typeset is a synonym for declare. See help declare in your bash shell. -p prints the attributes of a.
    – ibuprofen
    Jun 21, 2021 at 23:44

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.