Trying to have a multiple variable follow another variable, but I'm not getting 7 different VOL variables.
NME=(Y6T1 Y6-T1 Y6.T1 Yr6T1 Yr6-T1 Yr6.T1 Yr6Term1)
VOL=/Volumes/${NME}
for Copy in $VOL ; do
echo $Copy
done
In zsh
(since you seem to be using zsh
syntax), you'd do:
nme=(Y6T1 Y6-T1 Y6.T1 Yr6T1 Yr6-T1 Yr6.T1 Yr6Term1)
vol=(/Volumes/$^nme)
for Copy in $vol; do
printf '%s\n' $Copy
done
Without the ^
, /Volumes/$nme
would be the concatenation of /Volumes/
with the values of the array so only the first element would have /Volumes/
prepended to it.
Or, when assigning to a scalar variable instead of an array variable, like you did, it would be /Volumes/
concatenated with the array elements joined with the first character of $IFS
.
(note that the behaviour would be different in ksh
or bash
, where $nme
is just short for ${nme[0]}
).
Adding the ^
in $^nme
allows the concatenation to be distributed to each element of the array.
That ^
is reminiscent of rc
's ^
(non-)operator and possibly explains the origin of that ^
zsh variable expansion operator. In rc
:
nme=(Y6T1 Y6-T1 Y6.T1 Yr6T1 Yr6-T1 Yr6.T1 Yr6Term1)
vol=(/Volumes/^$nme)
for (Copy in $vol) printf '%s\n' $Copy
That ^
is not needed. vol=(/Volumes/$nme)
would work just the same. The point here is that rc
does distribute the concatenation. However ^
(which is just ignored and discarded) can be seen as a concatenation operator because it facilitates things like $nme^2
($nme2
would be treated as the nme2 variable, you'd need to write it $'nme'2
otherwise).
In bash
(also works in zsh
):
nme=(Y6T1 Y6-T1 Y6.T1 Yr6T1 Yr6-T1 Yr6.T1 Yr6Term1)
vol=("${nme[@]/#//Volumes/}")
for Copy in "${vol[@]}"; do
printf '%s\n' "$Copy"
done
Here, we're using the parameter leading pattern substitution operator (${param/#pattern/replacement}
) applied to each element of the array.
Here, we're replacing the empty string at the start of each element with /Volumes/
).
While that syntax comes from ksh93
, it doesn't work in ksh93
as it doesn't like that empty pattern. There, you need to replace ${nme[@]/#//Volumes/}
above with ${nme[@]/#@()//Volumes/}
for instance. @()
being an empty group.
Of course, in standard sh
syntax, you can always do:
set Y6T1 Y6-T1 Y6.T1 Yr6T1 Yr6-T1 Yr6.T1 Yr6Term1
for Copy do
printf '/Volumes/%s\n' "$Copy"
done
or:
set Y6T1 Y6-T1 Y6.T1 Yr6T1 Yr6-T1 Yr6.T1 Yr6Term1
for Copy do
Copy=/Volumes/$Copy
printf '%s\n' "$Copy"
done
Or if assuming your echo
(you should really get used to using printf
instead) was not just a place holder and all you want to do is display those one per line:
set Y6T1 Y6-T1 Y6.T1 Yr6T1 Yr6-T1 Yr6.T1 Yr6Term1
printf '/Volumes/%s\n' "$@"
Or:
printf '/Volumes/%s\n' Y6T1 Y6-T1 Y6.T1 Yr6T1 Yr6-T1 Yr6.T1 Yr6Term1
rc
's^
do? i sometimes get tripped up inzsh
on^
and never bothered to find out why. the problem usually happens when i screw up my terminal and needstty sane erase ^H
. also, probably you skipped it because its not really about variables, but it might be the asker just wantsprintf /Volumes/%s\\n 1 2 3 4 5
. people sometimes go out of their way to put stuff in variables, i think. – mikeserv Oct 28 '15 at 12:39rc
,^
is more like a non-operator. It's ignored but facilitates$var^something
which you'd have to be write$'var'something
otherwise. It's just that inrc
,x$array
(orx^$array
) and$'array'x
(or$array^x
), wherearray=(a b)
, expand toxa
xb
andax
bx
instead ofxa
b
ora
bx
. Inzsh
,$^array
enables a similar behaviour (it's different for$a^$b
in rc vs$^a$^b
in zsh though). Inzsh
,^
is an extendedglob negation operator. In the Bourne shell,^
is another name for|
. – Stéphane Chazelas Oct 28 '15 at 12:57