I would like to generate a number of arrays that differ only by year. In the loop, I create the arrays with brace expansion and a variable.
I tried the following code without success:
LIST={JF,JFE,RFS,JBF,JFI,JMCB}
for year in {1998..2000} {2009..2011}
do
declare -a 'y$year=('"$LIST"'-$year)'
echo "${y$year[@]}"
done
The outcome should be the list of the following entries:
y1998: JF-1998 JFE-1998 RFS-1998 JBF-1998 JFI-1998 JMCB-1998
y1999: JF-1999 JFE-1999 RFS-1999 JBF-1999 JFI-1999 JMCB-1999
...
y2011: JF-2011 JFE-2011 RFS-2011 JBF-2011 JFI-2011 JMCB-2011
I don't need to print them, just use them in a loop as well as pass them as arguments. Because of the second, eval
in the loop is not sufficient.
Best Answer
Deferring brace expansion is really a case for
eval
, particularly if you want to stringify things — ordinary parameter expansion doesn't do the right thing at the right time.This should do what it seems you wanted:
You can't indirect into an array, so it's necessary to stringify the array inside aneval
too if you want to print it out. If you don't, you can take out everything after the;
.tmp
is used for indirect expansion: withtmp
set to"y$year[@]"
, where$year
is replaced with its value, the expansion${!tmp}
gives the contents of this iteration's array (what${y1998[@]}
, etc, would have expanded to).The above will output:
and also create arrays
y1998
...y2011
. Thedeclare
s aren't strictly necessary, although they do let you skip aneval
if you're aiming for that and don't need to stringify.I suggest that this probably isn't the way you really want to achieve your underlying goal, though, whatever that is. Nested loops aren't evil, and if any bit of it's hardcoded you can abstract that out.