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?

1
  • Which release of bash, specifically? In 4.3 and newer, there's a namevar feature (borrowed from ksh) which allows a more robust implementation. Commented Sep 22, 2014 at 20:09

4 Answers 4

5

A task for eval:

itemnumber=1
(( itemnumber += 1))
eval "item$itemnumber=('item$itemnumber' '4' '77')"
eval echo \${item$itemnumber[*]} 
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, klashxx. So easy :D
3

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.

1 Comment

Now that I got Bash 4.3, the named references work magic! My game can now progress.
1

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

Comments

0

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 )

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.