Array variables getting lost

Array variables getting lost

am 17.01.2008 20:24:24 von Brian Greaney

Once again I need help!
I have the following segment of a script:
# #! /bin/bash
# PVCs
p=0
cut -f 1 -d, BT_00|
while IFS=, read PVC #loop through 1st field
do
p=$((++p))
pvc[$p]=$PVC
echo $p ${pvc[$p]}
done

echo "">>File1.xml
echo "$pvc[1]">>File1.xml
echo "$pvc[5]">>File1.xml
echo "${pvc[1]}">>File1.xml
echo " ss:Type=\"String\">${pvc[5]}">>File1.xml

For brevity I've left out some trivia, although this does actually execute
and gives the following:

1 CSAK205523
2 CSAK205547
3 CSAK205599
4 CSAK305545
5 CSAK309923

[1]
[5]



So in the 'loop' the correct variables are seen in the array (evidence
the CSAK.... )
But when I include them in the echo trying either $pvc[x] or ${pvc[x]} I
get either just the index or a null!

Where am I going wrong??

Re: Array variables getting lost

am 17.01.2008 20:44:50 von Janis Papanagnou

Brian Greaney wrote:
> Once again I need help!
> I have the following segment of a script:
> # #! /bin/bash
> # PVCs
> p=0
> cut -f 1 -d, BT_00|
> while IFS=, read PVC #loop through 1st field

According to the comment that should be...

while IFS=, read PVC DUMMY_VAR_FOR_FIELD_2_TO_END

I suppose? (Otherwise the whole line will be put in
variable PVC, despite any IFS definitions.)

Janis

> do
> p=$((++p))
> pvc[$p]=$PVC
> echo $p ${pvc[$p]}
> done
>
> echo "">>File1.xml
> echo "$pvc[1]">>File1.xml
> echo "$pvc[5]">>File1.xml
> echo "${pvc[1]}">>File1.xml
> echo " > ss:Type=\"String\">${pvc[5]}">>File1.xml
>
> For brevity I've left out some trivia, although this does actually execute
> and gives the following:
>
> 1 CSAK205523
> 2 CSAK205547
> 3 CSAK205599
> 4 CSAK305545
> 5 CSAK309923
>
> [1]
> [5]
>
>
>
> So in the 'loop' the correct variables are seen in the array (evidence
> the CSAK.... )
> But when I include them in the echo trying either $pvc[x] or ${pvc[x]} I
> get either just the index or a null!
>
> Where am I going wrong??

Re: Array variables getting lost

am 17.01.2008 20:48:41 von Brian Greaney

On Thu, 17 Jan 2008 20:44:50 +0100, Janis Papanagnou wrote:

> Brian Greaney wrote:
>> Once again I need help!
>> I have the following segment of a script:
>> # #! /bin/bash
>> # PVCs
>> p=0
>> cut -f 1 -d, BT_00|
>> while IFS=, read PVC #loop through 1st field
>
> According to the comment that should be...
>
> while IFS=, read PVC DUMMY_VAR_FOR_FIELD_2_TO_END
>
> I suppose? (Otherwise the whole line will be put in
> variable PVC, despite any IFS definitions.)
>
> Janis
>
>> do
>> p=$((++p))
>> pvc[$p]=$PVC
>> echo $p ${pvc[$p]}
>> done
>>
>> echo "">>File1.xml
>> echo "$pvc[1]">>File1.xml
>> echo "$pvc[5]">>File1.xml
>> echo "${pvc[1]}">>File1.xml
>> echo " >> ss:Type=\"String\">${pvc[5]}">>File1.xml
>>
>> For brevity I've left out some trivia, although this does actually execute
>> and gives the following:
>>
>> 1 CSAK205523
>> 2 CSAK205547
>> 3 CSAK205599
>> 4 CSAK305545
>> 5 CSAK309923
>>
>> [1]
>> [5]
>>
>>
>>
>> So in the 'loop' the correct variables are seen in the array (evidence
>> the CSAK.... )
>> But when I include them in the echo trying either $pvc[x] or ${pvc[x]} I
>> get either just the index or a null!
>>
>> Where am I going wrong??

But when I echo ${pvc[$p]} I do only see (correctly) the 1st field as the
cut 'must' have selected that?

Re: Array variables getting lost

am 17.01.2008 20:59:51 von Janis Papanagnou

Brian Greaney wrote:
> On Thu, 17 Jan 2008 20:44:50 +0100, Janis Papanagnou wrote:
>
>
>>Brian Greaney wrote:
>>
>>>Once again I need help!
>>>I have the following segment of a script:
>>># #! /bin/bash
>>># PVCs
>>>p=0
>>>cut -f 1 -d, BT_00|
>>>while IFS=, read PVC #loop through 1st field
>>
>>According to the comment that should be...
>>
>> while IFS=, read PVC DUMMY_VAR_FOR_FIELD_2_TO_END
>>
>>I suppose? (Otherwise the whole line will be put in
>>variable PVC, despite any IFS definitions.)
>>
>>Janis
>>
>>
>>>do
>>> p=$((++p))
>>> pvc[$p]=$PVC
>>> echo $p ${pvc[$p]}
>>>done
>>>
>>>echo "">>File1.xml
>>>echo "$pvc[1]">>File1.xml
>>>echo "$pvc[5]">>File1.xml
>>>echo "${pvc[1]}">>File1.xml
>>>echo " >>>ss:Type=\"String\">${pvc[5]}">>File1.xml
>>>
>>>For brevity I've left out some trivia, although this does actually execute
>>>and gives the following:
>>>
>>>1 CSAK205523
>>>2 CSAK205547
>>>3 CSAK205599
>>>4 CSAK305545
>>>5 CSAK309923
>>>
>>>[1]
>>>[5]
>>>
>>>
>>>
>>>So in the 'loop' the correct variables are seen in the array (evidence
>>>the CSAK.... )
>>>But when I include them in the echo trying either $pvc[x] or ${pvc[x]} I
>>>get either just the index or a null!
>>>
>>>Where am I going wrong??
>
>
> But when I echo ${pvc[$p]} I do only see (correctly) the 1st field as the
> cut 'must' have selected that?
>


$ echo "a,b,c,d" | bash -c 'while IFS=, read PVC rest ; do echo $PVC ; done'
a

$ echo "a,b,c,d" | bash -c 'while IFS=, read PVC ; do echo $PVC ; done'
a,b,c,d

If that's correct, then fine; I was just commenting on that single line.

Janis

Re: Array variables getting lost

am 17.01.2008 21:19:35 von Brian Greaney

On Thu, 17 Jan 2008 20:59:51 +0100, Janis Papanagnou wrote:

> Brian Greaney wrote:
>> On Thu, 17 Jan 2008 20:44:50 +0100, Janis Papanagnou wrote:
>>
>>
>>>Brian Greaney wrote:
>>>
>>>>Once again I need help!
>>>>I have the following segment of a script:
>>>># #! /bin/bash
>>>># PVCs
>>>>p=0
>>>>cut -f 1 -d, BT_00|
>>>>while IFS=, read PVC #loop through 1st field
>>>
>>>According to the comment that should be...
>>>
>>> while IFS=, read PVC DUMMY_VAR_FOR_FIELD_2_TO_END
>>>
>>>I suppose? (Otherwise the whole line will be put in
>>>variable PVC, despite any IFS definitions.)
>>>
>>>Janis
>>>
>>>
>>>>do
>>>> p=$((++p))
>>>> pvc[$p]=$PVC
>>>> echo $p ${pvc[$p]}
>>>>done
>>>>
>>>>echo "">>File1.xml
>>>>echo "$pvc[1]">>File1.xml
>>>>echo "$pvc[5]">>File1.xml
>>>>echo "${pvc[1]}">>File1.xml
>>>>echo " >>>>ss:Type=\"String\">${pvc[5]}">>File1.xml
>>>>
>>>>For brevity I've left out some trivia, although this does actually execute
>>>>and gives the following:
>>>>
>>>>1 CSAK205523
>>>>2 CSAK205547
>>>>3 CSAK205599
>>>>4 CSAK305545
>>>>5 CSAK309923
>>>>
>>>>[1]
>>>>[5]
>>>>
>>>>
>>>>
>>>>So in the 'loop' the correct variables are seen in the array (evidence
>>>>the CSAK.... )
>>>>But when I include them in the echo trying either $pvc[x] or ${pvc[x]} I
>>>>get either just the index or a null!
>>>>
>>>>Where am I going wrong??
>>
>>
>> But when I echo ${pvc[$p]} I do only see (correctly) the 1st field as the
>> cut 'must' have selected that?
>>
>
>
> $ echo "a,b,c,d" | bash -c 'while IFS=, read PVC rest ; do echo $PVC ; done'
> a
>
> $ echo "a,b,c,d" | bash -c 'while IFS=, read PVC ; do echo $PVC ; done'
> a,b,c,d
>
> If that's correct, then fine; I was just commenting on that single line.
>
> Janis
Good point, and thanks for the advice :)

Re: Array variables getting lost

am 17.01.2008 21:23:03 von Ed Morton

On 1/17/2008 1:24 PM, Brian Greaney wrote:
> Once again I need help!
> I have the following segment of a script:
> # #! /bin/bash
> # PVCs
> p=0
> cut -f 1 -d, BT_00|
> while IFS=, read PVC #loop through 1st field
> do
> p=$((++p))
> pvc[$p]=$PVC
> echo $p ${pvc[$p]}
> done
>
> echo "">>File1.xml
> echo "$pvc[1]">>File1.xml
> echo "$pvc[5]">>File1.xml
> echo "${pvc[1]}">>File1.xml
> echo " > ss:Type=\"String\">${pvc[5]}">>File1.xml
>
> For brevity I've left out some trivia, although this does actually execute
> and gives the following:
>
> 1 CSAK205523
> 2 CSAK205547
> 3 CSAK205599
> 4 CSAK305545
> 5 CSAK309923
>
> [1]
> [5]
>
>
>
> So in the 'loop' the correct variables are seen in the array (evidence
> the CSAK.... )
> But when I include them in the echo trying either $pvc[x] or ${pvc[x]} I
> get either just the index or a null!
>
> Where am I going wrong??

The loop is inside subshell courtesy of the pipe. See
http://www.unixguide.net/unix/bash/E4.shtml. Usually a loop is the wrong
approach to solve problems in shell.

In the above case, try this instead:

awk -F, '{
pvc[NR]=$1
print NR, pvc[NR]
}
END {
print ""
printf "%s\n",
pvc[1]
print "%s\n",
pvc[5]
}' BT_00 >> File1.xml

Regards,

Ed.

Re: Array variables getting lost

am 17.01.2008 21:50:39 von Brian Greaney

On Thu, 17 Jan 2008 14:23:03 -0600, Ed Morton wrote:

>
>
> On 1/17/2008 1:24 PM, Brian Greaney wrote:
>> Once again I need help!
>> I have the following segment of a script:
>> # #! /bin/bash
>> # PVCs
>> p=0
>> cut -f 1 -d, BT_00|
>> while IFS=, read PVC #loop through 1st field
>> do
>> p=$((++p))
>> pvc[$p]=$PVC
>> echo $p ${pvc[$p]}
>> done
>>
>> echo "">>File1.xml
>> echo "$pvc[1]">>File1.xml
>> echo "$pvc[5]">>File1.xml
>> echo "${pvc[1]}">>File1.xml
>> echo " >> ss:Type=\"String\">${pvc[5]}">>File1.xml
>>
>> For brevity I've left out some trivia, although this does actually execute
>> and gives the following:
>>
>> 1 CSAK205523
>> 2 CSAK205547
>> 3 CSAK205599
>> 4 CSAK305545
>> 5 CSAK309923
>>
>> [1]
>> [5]
>>
>>
>>
>> So in the 'loop' the correct variables are seen in the array (evidence
>> the CSAK.... )
>> But when I include them in the echo trying either $pvc[x] or ${pvc[x]} I
>> get either just the index or a null!
>>
>> Where am I going wrong??
>
> The loop is inside subshell courtesy of the pipe. See
> http://www.unixguide.net/unix/bash/E4.shtml. Usually a loop is the wrong
> approach to solve problems in shell.
>
> In the above case, try this instead:
>
> awk -F, '{
> pvc[NR]=$1
> print NR, pvc[NR]
> }
> END {
> print ""
> printf "%s\n",
> pvc[1]
> print "%s\n",
> pvc[5]
> }' BT_00 >> File1.xml
>
> Regards,
>
> Ed.
Many thanks again I will try that (tomorrow)
PS your last advice worked for me! Thanks

Re: Array variables getting lost

am 17.01.2008 21:56:07 von Ed Morton

On 1/17/2008 2:50 PM, Brian Greaney wrote:
> On Thu, 17 Jan 2008 14:23:03 -0600, Ed Morton wrote:
>
>
>>
>>On 1/17/2008 1:24 PM, Brian Greaney wrote:
>>
>>>Once again I need help!
>>>I have the following segment of a script:
>>># #! /bin/bash
>>># PVCs
>>>p=0
>>>cut -f 1 -d, BT_00|
>>>while IFS=, read PVC #loop through 1st field
>>>do
>>> p=$((++p))
>>> pvc[$p]=$PVC
>>> echo $p ${pvc[$p]}
>>>done
>>>
>>>echo "">>File1.xml
>>>echo "$pvc[1]">>File1.xml
>>>echo "$pvc[5]">>File1.xml
>>>echo "${pvc[1]}">>File1.xml
>>>echo " >>>ss:Type=\"String\">${pvc[5]}">>File1.xml
>>>
>>>For brevity I've left out some trivia, although this does actually execute
>>>and gives the following:
>>>
>>>1 CSAK205523
>>>2 CSAK205547
>>>3 CSAK205599
>>>4 CSAK305545
>>>5 CSAK309923
>>>
>>>[1]
>>>[5]
>>>
>>>
>>>
>>>So in the 'loop' the correct variables are seen in the array (evidence
>>>the CSAK.... )
>>>But when I include them in the echo trying either $pvc[x] or ${pvc[x]} I
>>>get either just the index or a null!
>>>
>>>Where am I going wrong??
>>
>>The loop is inside subshell courtesy of the pipe. See
>>http://www.unixguide.net/unix/bash/E4.shtml. Usually a loop is the wrong
>>approach to solve problems in shell.
>>
>>In the above case, try this instead:
>>
>>awk -F, '{
>> pvc[NR]=$1
>> print NR, pvc[NR]
>>}
>>END {
>> print ""
>> printf "%s\n",
>>pvc[1]
>> print "%s\n",
>>pvc[5]
>>}' BT_00 >> File1.xml
>>
>>Regards,
>>
>> Ed.
>
> Many thanks again I will try that (tomorrow)

Just change that last "print" to a "printf" before you do.

> PS your last advice worked for me! Thanks
>

You're welcome.

Ed.

Re: Array variables getting lost

am 19.01.2008 19:35:56 von Dan Mercer

"Brian Greaney" wrote in message news:pan.2008.01.17.19.25.49.685299@greaney-home.co.uk...
: Once again I need help!
: I have the following segment of a script:
: # #! /bin/bash
: # PVCs
: p=0
: cut -f 1 -d, BT_00|
: while IFS=, read PVC #loop through 1st field
: do
: p=$((++p))
: pvc[$p]=$PVC
: echo $p ${pvc[$p]}
: done
:
....
Where am I going wrong??
:
:
1. You haven't read the FAQ
2. You are using an inferior shell
3. You don't know what you're doing

Bash runs all segments of a pipeline in separate processes called subshells.
What happens in a subshell (directory changes, variable settings) stays
in the subshell. In ksh, the last element of a pipeline is executed in the
parent shell. So in ksh you would at least get the assignments to work.



Now, as to the "you don't know what you're doing" part:

presumably you have data in BT_00 that is comma delimited and you want the first
field. "cut -f 1 -d, BT_00" will give you that but it will not pass along the comma.
So what are you trying to do by setting IFS to ','? OTOH, if you want to process just
the first field of a comma delimited file AND do the processing in the current shell,
you would:


while IFS=, read field1 waste
do
...
done < file


BTW, if you have a comma separated file and you

while IFS=, read line;do ...;done
the $line will contain all the data from line 1 with comma's change to spaces.

Finally, you can do pipelines in bash with a little bit of syntactical magic:

$ while read a b c;do A=("${A[@]}" $a $b $c);done < <(echo -e "123 456 789\nABC DEF GHI")
$ for i in "${A[@]}";do echo "<$i>";done
<123>
<456>
<789>




Note that there are two "<" separated by a space. Depending on your OS, the pipeline will
either be fed into a special device file (/dev/fd0) or into a temporary fifo. That file
name will be passed to the program, in this case the shell. in effect you get:

while ...done < /dev/fd0

if you specify

while ...done <(list)

this would become

while ...done /dev/fd0

which, of course is a syntax error.

Dan Mercer

Re: Array variables getting lost

am 25.01.2008 21:47:59 von brian_hiles

"Dan Mercer" wrote:
> "Brian Greaney" wrote in messagenews:pan.2008.0=
1.17.19.25.49.685299@greaney-home.co.uk...
> > ...
> =A0 =A0 $ while read a b c;do A=3D("${A[@]}" $a $b $c);done < <(echo -e "1=
23 456 789\nABC DEF GHI")
> =A0 =A0 $ for i in "${A[@]}";do echo "<$i>";done
> ...
> Note that there are two "<" separated by a space.

Two separated by a space? I am not able to locate this feature
in an outdated version of a bash3 manpage.... I am aware of
process substitution, but where might I find more info concerning
this?

=3DBrian

Re: Array variables getting lost

am 25.01.2008 21:58:50 von Ed Morton

On 1/25/2008 2:47 PM, bsh wrote:
> "Dan Mercer" wrote:
>
>>"Brian Greaney" wrote in messagenews:pan.2008.01.17.19.25.49.685299@greaney-home.co.u k...
>>
>>>...
>>
>> $ while read a b c;do A=("${A[@]}" $a $b $c);done < <(echo -e "123 456 789\nABC DEF GHI")
>> $ for i in "${A[@]}";do echo "<$i>";done
>>...
>>Note that there are two "<" separated by a space.
>
>
> Two separated by a space? I am not able to locate this feature
> in an outdated version of a bash3 manpage.... I am aware of
> process substitution, but where might I find more info concerning
> this?

It's just replacing "file" with "<(echo...)" in this:

while read...done < file

Ed.