You are not logged in.
Solution: see my reply.
I know the description isn't exact, there really isn't an easy way to describe it with the limits of the title so the circumstances are these:
say I have arrays which contain small numbers like so:
ex. 12, 7 and 13
I which is greater than the other when comparing the following number in sequence and need to subtract the lower one from it. the 3 numbers above in that order will end up producing two simple problems:
(12 - 7) and (13 - 7). The results will be stored in an array in the order they were performed (left to right)
Currently I'm trying to accomplish this with a while loop and some if statements
Note: the array "Tree" is named such so I can print the results somewhat like so after performing this operation until only one result is left:
12 7 13
5 6
1
#!/usr/bin/env bash
Num_Set=( 12 7 13 )
A=0 ; B=1
while (( ${#Num_Set[B]} >= 1 )) ; do
if (( ${Num_Set[A]} >= ${Num_Set[B]} )) ; then
Tree[A]=$(( ${Num_Set[A]} - ${Num_Set[B]} ))
elif (( ${Num_Set[A]} < ${Num_Set[B]} )) ; then
Tree[A]=$(( ${Num_Set[B]} - ${Num_Set[A]} ))
fi
A=$(( A++ )) ; B=$(( B++ ))
done
echo "${Num_Set[@]}"
echo "${Tree[@]}"
I believe i'm on the right track but this becomes an endless loop for reasons unknown for to me.
Any bash hackers out there know whats happening here?
Last edited by Thme (2013-06-12 18:57:40)
"Hidden are the ways for those who pass by, for light is perished and darkness comes into being." Nephthys:
Ancient Egyptian Coffin Texts
Offline
You cannot increase A and B like that. ++A and ++B would work, or just ((A++)) ; ((B++))
Offline
Only a quick search but http://www.unix.com/shell-programming-s … array.html not sure it will help..
Mr Green
Offline
Ok So I solved it:
there were a couple problems with it and a few minor corrections..
I indeed switched to (( A++ )) and (( B++ )) right before I went back to seeif there were any replies here... I was more focused on getting it working but yes that is the way to do increments...
One issue to note was more so for any potential readers.
this syntax was wrong:
(( ${Num_Set[A]} - ${Num_Set[B]} ))
So far as I Learned you cannot reference array elements directly inside arithmetic operations "(( ))" so I had to store them as variables like so:
X=${Num_Set[A]} ; Y=${Num_Set[B]}
Tree+=( $(( X - Y )) )
The here is the working script (actually its a function for a larger script)
#!/usr/bin/env bash
Num_Set=( $@ )
A=0 ; B=1
N=${#Num_Set[B]}
while (( N != 0 )) ; do
X=${Num_Set[A]} ; Y=${Num_Set[B]}
if (( X >= Y )) ; then
Tree+=( $(( X - Y )) )
elif (( X < Y )) ; then
Tree+=( $(( Y - X )) )
fi
(( A++ )) ; (( B++ ))
N=${#Num_Set[B]}
done
echo "${Num_Set[@]}"
echo "${Tree[@]}"
Last edited by Thme (2013-06-12 18:55:19)
"Hidden are the ways for those who pass by, for light is perished and darkness comes into being." Nephthys:
Ancient Egyptian Coffin Texts
Offline
So far as I Learned you cannot reference array elements directly inside arithmetic operations "(( ))" so I had to store them as variables like so:
You can:
aa=( 1 0 )
echo $((${aa[${aa[0]}]} + ${aa[${aa[1]}]}))
1
echo $((${aa[${aa[1]}]} + ${aa[${aa[1]}]}))
2
Offline
Thme wrote:So far as I Learned you cannot reference array elements directly inside arithmetic operations "(( ))" so I had to store them as variables like so:
You can:
My bash allows this, too:
a=(1 2 3)
b=1
echo $(( a[b] ))
echo $(( a[b] + a[2] ))
| alias CUTF='LANG=en_XX.UTF-8@POSIX ' |
Offline
@ progandy. Completely forgot that... So my previous post and this one currently works:
I will mention this though you can't use this:
a=( 12 7 345 )
if (( #a[1] < #a[0] )) ; then echo "${a[1]}" ; fi
Note: It is actually the full function. The part which was the focus of my post is the inner/second while loop here.
Num_Set=( $@ )
Set=( ${Num_Set[@]} )
Count=${#Set[@]}
while (( Count > 1 )) ; do
A=0 ; B=1
N=${#Num_Set[B]}
while (( N != 0 )) ; do
if (( Num_Set[A] >= Num_Set[B] )) ; then
Tree+=( $(( Num_Set[A] - Num_Set[B] )) )
Tmp+=( $(( Num_Set[A] - Num_Set[B] )) )
elif (( Num_Set[A] < Num_Set[B] )) ; then
Tree+=( $(( Num_Set[B] - Num_Set[A] )) )
Tmp+=( $(( Num_Set[B] - Num_Set[A] )) )
fi
(( A++ )) ; (( B++ ))
N=${#Num_Set[B]}
done ; wait
(( Count-- ))
Num_Set=( ${Tmp[@]} )
unset Tmp[@]
done
echo "${Num_Set[@]}"
echo "${Tree[@]}"
@ Procyon I've recently read that although you can still use $ inside (( )) it isn't necessary/recommended as progangy demonstrates. Anyhow, I appreciate the corrections and help here. It's all working the way I wanted it to now.
Last edited by Thme (2013-06-13 02:56:10)
"Hidden are the ways for those who pass by, for light is perished and darkness comes into being." Nephthys:
Ancient Egyptian Coffin Texts
Offline
I will mention this though you can't use this:
a=( 12 7 345 ) if (( #a[1] < #a[0] )) ; then echo "${a[1]}" ; fi
@ Procyon I've recently read that although you can still use $ inside (( )) it isn't necessary/recommended as progangy demonstrates. Anyhow, I appreciate the corrections and help here. It's all working the way I wanted it to now.
You're checking the length of the string with #. (so 12 7 345 -> 2 1 3)
You can change this:
N=${#Num_Set[B]}
while (( N != 0 )) ; do
With just while [[ ${Num_Set[$B]} ]]; do
And bash has associative arrays as well. Your claim that the $ is not recommended is not valid at all:
declare -A aa
aa[bb]=100
aa[0]=1
bb=0
echo $(( aa[bb] + 1 ))
101
echo $(( aa[$bb] + 1 ))
2
Offline
(this is not the post you're looking for, move along)
Last edited by Trent (2013-06-13 22:11:22)
Offline
And bash has associative arrays as well. Your claim that the $ is not recommended is not valid at all:
declare -A aa aa[bb]=100 aa[0]=1 bb=0 echo $(( aa[bb] + 1 )) 101 echo $(( aa[$bb] + 1 )) 2
My apologies however I tested my original post with http://www.shellcheck.net/ upon finding the site through an unrelated thread. This was an example test to illustrate what was commented on and what was not. This works in the shell:
A=( 2 1 10 )
B=2
echo $(( A[0] + A[B] - ${A[${A[$B]}]} - A[$B] + ${A[A[1]]} + A[0] - ${#A[2]} ))
23
However ${A[${A[$B]}]} and ${A[A[1]]} were commented on by shellcheck with "don't use $ on variables in (( ))". Aside from that it does still work. Also I tested this as well:
echo $(( A[${A[0]}] + 1 ))
And although it works in my bash it gets "This $((..)) expression is malformed." and "Unexpected "}". Fix any mentioned problems and try again." when tested in shellcheck. I suspect that maybe a fault on shellcheck but either way it looks less readable than just A[A[0]]. So what I've gathered from all this is that, although the above examples all work, the following ones below are probably the best practice here for use in (( )).
#!/usr/bin/env bash
declare -A AA
AA[BB]=3
AA[0]=1
BB=0
A=( 2 1 10 )
B=1
echo $(( A[0] + 1 ))
echo $(( B + 1 ))
echo $(( A[0] + 1 ))
echo $(( A[B] + 1 ))
echo $(( A[A[0]] + 1 ))
echo $(( ${#A[2]} + 1 ))
echo $(( ${A[2]/0/1} + 1 ))
echo $(( A[BB] + 1 ))
echo $(( AA[$BB] + 1 ))
echo $(( AA[BB]++ ))
So in the cases of using arrays in manners like ${#A[2]}, ${A[2]/0/1} and AA[$BB] ( AA[BB] being different. ) using $ would be necessary inside of (( )). If I missed any or there are any needed corrections please note them as I'm concerned with good practices here. I'll leave it at that. Again thanks for the help everyone.
Last edited by Thme (2013-06-15 00:49:54)
"Hidden are the ways for those who pass by, for light is perished and darkness comes into being." Nephthys:
Ancient Egyptian Coffin Texts
Offline