[Cialug] Bash looping issue
Crouse
crouse at usalug.net
Wed Oct 13 15:12:40 CDT 2010
On Wed, Oct 13, 2010 at 1:14 PM, Crouse <crouse at usalug.net> wrote:
> ah nm... that went horribly wrong ;)
>
>
> On Wed, Oct 13, 2010 at 1:12 PM, Crouse <crouse at usalug.net> wrote:
>> On Wed, Oct 13, 2010 at 11:18 AM, Ken MacLeod <ken at bitsko.slc.ut.us> wrote:
>>> On Tue, Oct 12, 2010 at 10:07 AM, Daniel A. Ramaley
>>> <daniel.ramaley at drake.edu> wrote:
>>>> In the example script below, i define an associative array and then make
>>>> a copy of it using a loop to copy each key/value pair. It seems to work
>>>> quite nicely... within the loop. Once outside the loop, the copied array
>>>> loses its data. The bizarre thing is that if i switch the loop construct
>>>> from a "while" to a "for", it works.
>>>
>>>> # Comment out the "printf...while" loop and comment in the "for" loop
>>>> # and it magically starts working. I don't know why.
>>>> printf "%s\000" "${!ORIG[@]}" | sort -z | while read -d $'\0' key ; do
>>>> #for key in "${!ORIG[@]}" ; do
>>>
>>> My first thought is that the "while" is running in a pipeline so it's
>>> running in a subprocess rather than the current process, so any
>>> variables inside the loop are local to the subprocess. However, I
>>> thought I've done that before too and it worked right...
>>>
>>> You might try:
>>>
>>> while read -d $'\0' key <(printf "%s\000" "${!ORIG[@]}" | sort -z); do
>>>
>>> so the printf | sort runs in a background process and the while stays
>>> in the current process. I've never tried that before but it popped up
>>> when I went looking for the other kinds of "fancy" pipe handling that
>>> I know bash has ;-)
>>>
>>> -- Ken
>>> _______________________________________________
>>> Cialug mailing list
>>> Cialug at cialug.org
>>> http://cialug.org/mailman/listinfo/cialug
>>>
>>
>> If your just copying an array, do you need to use the while loop ?
>>
>> #!/bin/bash
>> declare -A ORIG
>> ORIG=(['key 1']='A'
>> ['key 2']='B'
>> ['key 3']='C')
>>
>> COPY=("${ORIG[@]}")
>>
>> echo -e "\nORIG\n----"
>> for key in "${!ORIG[@]}" ; do # Prints the ORIG array.
>> echo -e "$key\t${ORIG[$key]}"
>> done
>>
>> echo -e "\nCOPY\n----"
>> for key in "${!COPY[@]}" ; do # Prints COPY only if it was created
>> echo -e "$key\t${COPY[$key]}" # with "for" loop--prints nothing if
>> done # created with "while".
>>
>
Well after some looking, I found this:
http://mywiki.wooledge.org/BashGuide/Arrays
"the order of the keys you get back from an associative array using
the ${!array[@]} syntax is unpredictable; it won't necessarily be the
order in which you assigned elements, or any kind of sorted order. "
Handy..... not sure this really helps at all, but I did find it interesting.
#!/bin/bash
declare -A ORIG
ORIG=(['key 1']='A'
['key 2']='B'
['key 3']='C')
declare -A COPY
# Create list of keys
for key in "${!ORIG[@]}" ; do
echo "$key" >> temp
done
# Sort list of keys
cat temp | sort > temp2
while read mykey ; do
COPY["${mykey}"]="${ORIG[$mykey]}"
#COPY+=(["${key}"]="${ORIG[$key]}") # Alternate form of assignment
echo -e "DEBUG:\tProcessing key=\"${mykey}\", val=\"${ORIG[$mykey]}\""
# echo -e "DEBUG:\t${!COPY[@]}\nDEBUG:\t${COPY[@]}" ; # Shows changes
done < temp2
# remove temp files
rm temp temp2
#for key in "${!ORIG[@]}" ; do
# COPY["${key}"]="${ORIG[$key]}"
#COPY+=(["${key}"]="${ORIG[$key]}") # Alternate form of assignment
# echo -e "DEBUG:\tProcessing key=\"${key}\", val=\"${ORIG[$key]}\""
# echo -e "DEBUG:\t${!COPY[@]}\nDEBUG:\t${COPY[@]}" ; # Shows changes
#done<( printf "%s\000" "${!ORIG[@]}" | sort -z )
echo -e "\nORIG\n----"
for key in "${!ORIG[@]}" ; do # Prints the ORIG array.
echo -e "$key\t${ORIG[$key]}"
done
echo -e "\nCOPY\n----"
for key in "${!COPY[@]}" ; do # Prints COPY only if it was created
echo -e "$key\t${COPY[$key]}" # with "for" loop--prints nothing if
done # created with "while".
~
~
~
~
~
~
~
~
~
~
~
~
~
[crouse at Archie] ~
> ./cialug
DEBUG: Processing key="key 1", val="A"
DEBUG: Processing key="key 2", val="B"
DEBUG: Processing key="key 3", val="C"
ORIG
----
key 1 A
key 3 C
key 2 B
COPY
----
key 1 A
key 3 C
key 2 B
More information about the Cialug
mailing list