bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Problem with how to assign an array


From: Ken Irving
Subject: Re: Problem with how to assign an array
Date: Thu, 24 Feb 2011 13:00:33 -0900
User-agent: Mutt/1.5.20 (2009-06-14)

On Thu, Feb 24, 2011 at 03:42:57PM -0500, Greg Wooledge wrote:
> On Thu, Feb 24, 2011 at 02:55:13PM -0500, Steven W. Orr wrote:
> > I have three arrays
> > 
> > a1=(aaa bbb ccc ddd)
> > a2=(qqq www eee rrr)
> > a3=(fff ggg hhh)
> > 
> > I then set a_all
> > 
> > a_all=("${a1[*]}" "${a2[*]}" "${a3[*]}"
> 
> Missing ).  Also, a far more serious problem, you used * when you should
> have used @.
> 
> a_all=("${a1[@]}" "${a2[@]}" "${a3[@]}")
> 
> This is absolutely critical.  Without this, you are no longer maintaining
> the integrity of each element.  In fact, what you've got there will create
> a_all with precisely 3 elements.  Each of these elements will be a
> concatenation of the other arrays' elements with a space (or the first
> char of IFS if you've set that) between them.
> 
> > Later on, I decide which element of a_all I really want. So with my new 
> > index calculated, I say
> > 
> > real_a=( ${a_all[index]} )
> 
> This is also wrong.  This one does word-splitting on the element you're
> indexing, and the resulting set of words becomes a new array.

But if * was used in declaring the a_al elements, this _would_ recover
one of the arrays, e.g., real_a=(${a_all[1]}) should result in the same
array as a2.  (Ignoring the null-element issue, though.)

I had the same thought, use @ instead of *, but maybe the OP wants to 
get the original arrays and not individual elements?

> In fact, I can only guess what you're trying to do here.
> 
> If you want to assign a single element to a scalar variable, you
> should do:  element=${array[index]}
> 
> > And it worked really well until today. The problem is that I need an 
> > element of the aNs to be allowed to be null values.
 
As explained, using * expands '' or ' ' into just word-delimiting whitespace,
so the null elements are lost.

> No problem.
> 
> > Like this:
> > 
> > a1=(aaa bbb ccc ddd '' jjj kkk lll)
> 
> No problem.
> 
> > such that if index is 0, I'd like real_a to end up with 8 elements instead 
> > of 7.
> 
> Huh?  You mean during the concatenation?  (You changed the array name?)
> Do it correctly:
> 
> imadev:~$ unset a1 a2 big; a1=(a b '' c) a2=(d e f '')
> imadev:~$ big=("${a1[@]}" "${a2[@]}")
> imadev:~$ printf "<%s> " "${big[@]}"; echo
> <a> <b> <> <c> <d> <e> <f> <> 
> 
> > I could create a sentinel, I could use a case statement, I could create all 
> > kinds of confabulations, but I'd like to know if there's a better way to do 
> > it.
> 
> Huh?

If by sentinel you (OP) mean a token standing in for null, I suspect that would
be the simplest approach.

> > I literally tried everything I could think of.

Listen to Greg... 

Ken

> You must learn the difference between "$*" and "$@".  (And the analogous
> treatment of * and @ in an array indexing context.)
> 
> imadev:~$ wrong=("${a1[*]}" "${a2[*]}")
> imadev:~$ printf "<%s> " "${wrong[@]}"; echo
> <a b  c> <d e f > 
> 
> If you don't use the right syntax, you're going to have problems with
> elements that contain whitespace (or IFS characters) as well as empty
> elements as you already noted.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]