0

I'm currently learning script shell programming(bash), and trying to make multiple arrays with different names by looping so that I could put the data according to the length of my data files. I've done getting the length of the data file(marked as 'num'), and here's what I could think in my brain.

for (( i=0; i<num; i++ ))
do  
    let array$i=()
done

I've looked up many method but it didn't work. I'm a newbie to bash so any comments / recommendations / teachings would be so appreciated. Thank you.

Chocode
  • 147
  • 9
  • 1
    What you are looking for is probably namerefs (with a recent enough version of bash), or indirection. Just type `man bash` and then search for one or the other. Note: `let` is not what you apparently think. In bash it introduces arithmetic expressions. – Renaud Pacalet Feb 15 '22 at 12:32
  • @RenaudPacalet : How can a nameref be used to dynamically create a set of arrays? I only know how we can use it to refer to an existing variable, i.e. we have manually created a number of arrays and use a nameref to dynamically refer to one of them. The OPs problem seems to be to actually create the arrays, without explicitly naming them. Of course, an `eval arr$i=(....)` would work, but is ugly and error-prone. – user1934428 Feb 15 '22 at 13:43
  • See [Creating a string variable name from the value of another string](https://stackoverflow.com/questions/13716607/creating-a-string-variable-name-from-the-value-of-another-string), [How can I generate new variable names on the fly in a shell script?](https://stackoverflow.com/questions/10820343/how-can-i-generate-new-variable-names-on-the-fly-in-a-shell-script), and [Dynamic variable names in Bash](https://stackoverflow.com/q/16553089/4154375). – pjh Feb 15 '22 at 13:46
  • Does this answer your question? [Dynamic variable names in Bash](https://stackoverflow.com/questions/16553089/dynamic-variable-names-in-bash) – pjh Feb 15 '22 at 13:47
  • Actually, no. I think I want something like `arr1=(), arr2=(), arr3=()` these kinds of things after loop iterations. Because I need to insert data into these array and I can't define how many arrays are needed because it depends on the file length. – Chocode Feb 15 '22 at 13:57
  • 1
    @user1934428 Easy. Always use the same nameref but let it point to different variable names: `declare -n nr=array1`, then do whatever you want with variable `nr`, it will be the same as if you do it with variable `array1`. Example: `nr=([foo]=1 [bar]=2); printf '%s\t%s\n' "${!array1[@]}" "${array1[@]}"` will print `foo\tbar\n1\t2\n`. Give it a try. Next you can `declare -n nr=array2` and start working with your second array. And of course you can `declare -n nr="array$i"` if you wish. – Renaud Pacalet Feb 15 '22 at 14:25

1 Answers1

2

With a recent enough bash, using namerefs:

for (( i=0; i<num; i++ )); do  
  declare -n nr="array$i"
  declare -a nr=()
done

And then, each time you want to add elements to your array10:

i=10
declare -n nr="array$i"
nr+=( foo bar )

To access the elements you can use the nameref (nr) or the array name, it works the same (as long as you do not modify the nameref attribute):

$ i=10
$ declare -n nr="array$i"
$ printf '%s\n' "${nr[@]}"
foo
bar
$ printf '%s\n' "${array10[@]}"
foo
bar

Think of it as a kind of reference.

Renaud Pacalet
  • 25,260
  • 3
  • 34
  • 51