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:
LIST={JF,JFE,RFS,JBF,JFI,JMCB}
for year in {1998..2000} {2009..2011}
do
eval "y$year=($LIST-$year)"
tmp="y$year[@]"
echo "${!tmp}"
done
You can't indirect into an array, so it's necessary to stringify the array inside an eval
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: with tmp
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:
JF-1998 JFE-1998 RFS-1998 JBF-1998 JFI-1998 JMCB-1998
JF-1999 JFE-1999 RFS-1999 JBF-1999 JFI-1999 JMCB-1999
JF-2000 JFE-2000 RFS-2000 JBF-2000 JFI-2000 JMCB-2000
JF-2009 JFE-2009 RFS-2009 JBF-2009 JFI-2009 JMCB-2009
JF-2010 JFE-2010 RFS-2010 JBF-2010 JFI-2010 JMCB-2010
JF-2011 JFE-2011 RFS-2011 JBF-2011 JFI-2011 JMCB-2011
and also create arrays y1998
...y2011
. The declare
s aren't strictly necessary, although they do let you skip an eval
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.
This is really easy, actually, First, you need to set aside your stdin in some remembered descriptor:
exec 9<&0
There. You've made a copy. Now, let's pipe our commands at our shell.
echo 'echo foo; read <&9; echo bar' | bash
...well, that was easy. Of course, we're not really done yet. We should clean up.
exec 9<&-
Ok, now we're done.
But we can avoid the cleanup if we just group our commands a little...
{ echo 'echo foo; read <&9; echo bar' | bash; } 9<&0
The descriptor only survives as long as its assigned compound command does in that case.
Best Answer
The reason for this is the order in which things occur in bash. Brace expansion occurs before variables are expanded. In order to accomplish your goal, you need to use C-style for loop: