This will do what you want (more or less). As larkost implies, arrays in Bash are one-dimensional... so a combination of tricks and tradeoffs are needed to pull it off.
A few comments first...
Originally Posted by
kman42
#!/bin/sh
Really should shebang with
#!/bin/bash to be true-to-form (sh doesn't do arrays, technically speaking).
Originally Posted by
kman42
period=(${spikes},${duration},${interval},${lag});
Looks nice on paper, and Bash doesn't bark. But -- if/when that gets treated as an array -- it only has
one element (e.g., 1,2,3,4). (Else, another choice might be to assign the array elements on the fly, with each of those read operations:
read period[0]; read period[1]; read period[2]; read period[3]. But still, putting that array into the period
s array would just result in one big array).
Originally Posted by
kman42
thisperiod=${periods[$p]}
:
echo "zero element of thisperiod= ${thisperiod[0]}
As noted above, the items going into periods (e.g., 1,2,3,4) are not arrays themselves (or at best are single-element arrays). So basically $thisperiod is just a
string and therefore
${thisperiod[0]} means nothing (nothing expected anyway). See below for how to still make it functional (as long as real indexing doesn't matter).
I had fun brushing up on (and adding to) my knowledge of array syntax while coming up with this... so here it is:
Code:
#!/bin/bash -
IFS=$' \t\n'
declare -x PATH=/bin:/usr/bin
declare -a PERIODS
printf "How many periods? "
read j
for ((i=1; i<=$j; i++)) # Load data...
do
printf "\n$i/$j:\nHow many spikes in period $i? "
read spikes
printf "What is the duration of the spikes for period $i? "
read duration
printf "What is the interval between spikes for period $i? "
read interval
printf "What is the lag time before the next period? "
read lag
# Splice the "elements" together, using commas (or some char) as glue:
period=$spikes,$duration,$interval,$lag # <--a multi-parameter string.
echo "period $i = $period"
PERIODS=( "${PERIODS[@]}" "$period" ) # The only real (indexed) array.
done
echo
echo "$j periods: ${PERIODS[@]}" # printf trips up with arrays, must use echo.
sleep 1
for ((p=0; p<${#PERIODS[@]}; p++))
# Note that: ${#PERIODS[@]} will likely get the same value as "$j" already is.
do
printf "\nperiod %d:\n" $(($p+1))
# Unglue the pieces of each period by converting commas into spaces...
# and then (instead of using indexes) just iterate over existing data:
for s in ${PERIODS[$p]//,/ } # Bash parameter expansion w/substitution
do
echo "s = $s"
done
done
exit $?
In order for this to work, the items going into each "period" must not contain spaces themselves... else the expansion trick will wind up iterating over more s values than desired. Finally (as also noted by larkost), other languages such as Perl are better built for this sort of thing.
--
EDIT: on further thought, if one absolutely wanted to have
array indexes for that final inner do-loop, then the expansion/substitution could be assigned into a new array...
Code:
printf "\nperiod %d:\n" $(($p+1))
# Unglue the pieces of each period (convert the commas into spaces) by
# using parameter expansion w/substitution to fabricate a new array...
thisPeriod=( ${PERIODS[$p]//,/ } )
for ((s=0; s<${#thisPeriod[@]}; s++))
do
echo "data [$p,$s] = ${thisPeriod[$s]}"
done
...but the advantage of doing so (if any) is not readily apparent (at least not in terms of that single echo statement given in post #1).