Alichino
Alichino

Reputation: 1736

BASH - A variable as part of array name (part 2)

Let's say I start with just item1=('item1' '1' '20')

I then define itemnumber=2

I would like to create the next array as item$itemnumber=('item2' '4' '77'), but I get a syntax error.

After that I would like to just do itemnumber=$((itemnumber+1)), and create item$itemnumber=('item3' '17' '15')

Which would give me three arrays item1, 2 and 3:

item1=('item1' '1' '20')
item2=('item2' '4' '77')
item3=('item3' '17' '15')

Is this possible?

Upvotes: 2

Views: 369

Answers (4)

Charles Duffy
Charles Duffy

Reputation: 295308

In bash 4.3, a namevar is the perfect tool:

set_item() {
  local itemnumber=$1; shift
  local -n array_name="item$itemnumber"
  array_name=( "$@" )
}
set_item 2   1 2 3 4
set_item 3   2 3 4 5

...will have the same effect as...

item2=( 1 2 3 4 )
item3=( 2 3 4 5 )

Upvotes: 0

clt60
clt60

Reputation: 63892

A bit late answer, but if you need this many times, you can use an function for assign

#!/bin/bash

assign () { eval "$1=($(printf '"%s" ' "$@"))"; }

itemnum=0
assign item$((++itemnum)) 1 2 3 4
assign item$((++itemnum)) 'q w e r'
assign item$((++itemnum)) a "$itemnum cc" dd  

#show the array members enclosed in ''
echo "item1:" $(printf "'%s' " "${item1[@]}")
echo "item2:" $(printf "'%s' " "${item2[@]}")
echo "item3:" $(printf "'%s' " "${item3[@]}")

prints

item1: 'item1' '1' '2' '3' '4'
item2: 'item2' 'q w e r'
item3: 'item3' 'a' '3 cc' 'dd'

or simple

echo ${item1[@]}
echo ${item2[@]}
echo ${item3[@]}

prints

item1 1 2 3 4
item2 q w e r
item3 a 3 cc dd

if you want exclude, the first element from the array (the itemname), use

assign () { var="$1"; shift 1; eval "$var=($(printf '"%s" ' "$@"))"; }

n=0
assign item((++n)) 1 2 3 4
echo "item1 contains only: $item1[@]}"

prints

item1 contains only: 1 2 3 4

Upvotes: 1

chepner
chepner

Reputation: 530960

Use the declare command, although you'll need to modify how you perform the assignment.

declare -a "item$itemnumber"
declare "item$itemnumber+=(item$itemnumber 4 77)

In bash 4.3, this is greatly simplified with named references.

itemnumber=0
declare -n arr=item$itemnumber
arr+=(item$itemnumber 1 20)
((itemnumber++))
declare -n arr=item$itemnumber
arr+=(item$itemnumber 4 77)
((itemnumber++))
declare -n arr=item$itemnumber
arr+=(item$itemnumber 17 15)

Just increment itemnumber, reset the reference, then use the reference as you would the actual array.

Upvotes: 3

Juan Diego Godoy Robles
Juan Diego Godoy Robles

Reputation: 14945

A task for eval:

itemnumber=1
(( itemnumber += 1))
eval "item$itemnumber=('item$itemnumber' '4' '77')"
eval echo \${item$itemnumber[*]} 

Upvotes: 5

Related Questions