Register
It is currently Tue Sep 23, 2014 8:21 am

Array - Not Working As I Thought?!


All times are UTC - 6 hours


Post new topic Reply to topic  [ 7 posts ] 
Author Message
 PostPosted: Wed Apr 15, 2009 4:22 am   

Joined: Wed Apr 15, 2009 4:17 am
Posts: 3
Location: UK
Hi Guys,

I'm writing a very simple script, it currently checks for certain files (Will Do).. However when I'm attempting to read from an array when i use ${arrayname[1]} nothing is returned, but when i use ${arrayname[@]} the whole array is returned.. Below is my script... (Very simple i know!) Well if you have any idea's or pointers let me know...

Code:
#!/bin/bash
#Script to move 50 files at a time from the selected GPRSS Station
# By Tom Buchanan - First Bash Script!
# File Formats:
#To Old Messages: Too-old-27af9abd.msg or Too-old-27af9abd.msg
#To Lost-msg: /usr/medway/GPRSS1/GBP/bin/lost-msg
#To Recovery-msg: /usr/medway/GPRSS1/GBP/bin/recovery-msg


MEDWAYPATH="/usr/medway";
LOSTMSGPATH="/GBP/bin/lost-msg";
COUNT=0;
declare -a RETRYMSG
declare -a OLDMSG
declare -a GPRSS

#Find GPRSS DIRS
GPRSS_LIST="`ls ${MEDWAYPATH} | grep GPRSS`";
if [ "$GPRSS_LIST" = "" ];
then
        echo "NO GPRSS Folders Found in $MEDWAYPATH";
        exit;
else
        for list in ${GPRSS_LIST};
         do
                MSGCHECK="`ls ${MEDWAYPATH}/${list}${LOSTMSGPATH} | egrep Too-old | wc -l`";
                OLD_LIST="$OLD_LIST $MSGCHECK";
                MSGCHECK="`ls ${MEDWAYPATH}/${list}${LOSTMSGPATH} | egrep Retry | wc -l`";
                RETRY_LIST="$RETRY_LIST $MSGCHECK";
        done;

        for list in ${GPRSS_LIST};
         do
                GPRSS[$COUNT]=${list};
                ((COUNT++));
         done
        for list in ${OLD_LIST};
         do
                OLDMSG[$COUNT]=${list};
                echo "test ${list}";
                ((COUNT++));
         done

        for list in ${RETRY_LIST};
         do
                RETRYMSG[$COUNT]=${list};
                ((COUNT++));
         done

fi

echo "Too-old messages ${OLDMSG[@]}";
echo "Retry messages ${RETRYMSG[@]}";
echo " test Retry Field  3:  "${OLDMSG[3]}" "
echo GPRSS Station List; echo "---------------"
echo -e "No.\tGPRSS\t|\tRetry MSGs\t|\tOld MSGs"

COUNT=0;
for list in ${GPRSS_LIST};
        do
                echo -e $COUNT:  "\t"$list"\t"${RETRYMSG[$COUNT]};
                ((COUNT++));
done;


echo Please make your Selection 1 to $COUNT:
read GPRSS
echo -e "You Selected \t$GPRSS"


Currently the script returns:

tomehb@tServer:~/Scripts$ ./recovery-msg.sh
test 3
test 0
test 0
test 0
test 0
test 0
Too-old messages 3 0 0 0 0 0
Retry messages 0 0 6 0 0 0
Retry Field 3:
GPRSS Station List
---------------
No. GPRSS | Retry MSGs | Old MSGs
0: GPRSS1
1: GPRSS2
2: GPRSS3
3: GPRSS4
4: GPRSS6
5: GPRSS88
Please make your Selection 1 to 6:
1
You Selected 1


Top
 Profile WWW  
 PostPosted: Wed Apr 15, 2009 4:41 am   

Joined: Mon Nov 17, 2008 7:25 am
Posts: 221
Hum, that should work fine.

Just a few pointers for future references :)
One thing thou is you're not forced to quote the array variable name, "${array[1]}" is superfluous. ${array[1]} is sufficient.
All the semicolon's you've used are also not needed but this shouldn't pose a problem in your script.
Only place you really need to specify a variable with {} is when you use either something like $typename where $type is the variable name (${type}name) or when you're doing arrays.

As I see it the list is correct. Apperantly the OLD_LIST contains the numbers 3 0 0 0 0 0 and that is what is printed.
If this is not correct then something is wrong when it inputs the value into the array.

What results do you get if you manually run ls ${MEDWAYPATH}/${list}${LOSTMSGPATH} | egrep Too-old | wc -l?

Edit: ps. use "grep" if you're not going to do regularexpression greps instead of egrep. Egrep is slower by default :) ds.

Best regards
Fredrik eriksson


Top
 Profile  
 PostPosted: Wed Apr 15, 2009 6:27 am   

Joined: Wed Apr 15, 2009 4:17 am
Posts: 3
Location: UK
fredrik.eriksson wrote:
Hum, that should work fine.

Just a few pointers for future references :)
One thing thou is you're not forced to quote the array variable name, "${array[1]}" is superfluous. ${array[1]} is sufficient.
All the semicolon's you've used are also not needed but this shouldn't pose a problem in your script.
Only place you really need to specify a variable with {} is when you use either something like $typename where $type is the variable name (${type}name) or when you're doing arrays.

As I see it the list is correct. Apperantly the OLD_LIST contains the numbers 3 0 0 0 0 0 and that is what is printed.
If this is not correct then something is wrong when it inputs the value into the array.

What results do you get if you manually run ls ${MEDWAYPATH}/${list}${LOSTMSGPATH} | egrep Too-old | wc -l?

Edit: ps. use "grep" if you're not going to do regularexpression greps instead of egrep. Egrep is slower by default :) ds.

Best regards
Fredrik eriksson


I also thought it should work, thanks for the tips I've removed all of the semicolon's and changed egrep to grep...

I ran the following like you suggested ..

tomehb@tServer:~/Scripts$ ls /usr/medway/GPRSS1/GBP/bin/lost-msg/ | grep Too-old | wc -l
3
tomehb@tServer:~/Scripts$ ls /usr/medway/GPRSS2/GBP/bin/lost-msg/ | grep Too-old | wc -l
0
tomehb@tServer:~/Scripts$ ls /usr/medway/GPRSS3/GBP/bin/lost-msg/ | grep Too-old | wc -l
0


So I'm still confused :( Are there any other things i should test? Thanks for your help btw


Top
 Profile WWW  
 PostPosted: Wed Apr 15, 2009 7:53 am   

Joined: Mon Nov 17, 2008 7:25 am
Posts: 221
This example code worked fine for me.
Code:
#!/bin/bash
declare -a array
x=0
for i in $(seq 1 5); do
   array[$x]=$i
   ((x++))
done

x=0
# Print the array :)
echo "array: ${array[@]}"
# Print the array using a for loop instead of @. This reveals if the elements are in order.
echo -n "values: "
for i in $array[@]; do
   echo -n "{$array[$x]} "
   ((x++))
done
echo
# Just test a random array element and see if it shows everything correctly
echo "random value: ${array[2]}"


This gives me the following output
sajko@hanna:~>./tst.sh
array: 1 2 3 4 5
value: 1 2 3 4 5
random value: 2

But I do think I see a design flaw... your count variable is never resetted.
The value in $OLDMSG[2] is not there and it's never been... lets say that the array using count is 3 elements long, then the count variable will be 3.
On the next pass (with a new array) then the counter will start at 3 making the first element number 3 instead of 0.
So, basically the number you're trying to use really is empty and never will contain anything unless the other arrays contain 0 elements.

Best regards
Fredrik Eriksson


Top
 Profile  
 PostPosted: Wed Apr 15, 2009 4:47 pm   

Joined: Wed Apr 15, 2009 4:17 am
Posts: 3
Location: UK
God thankyou :) I tried your script though and it gave the following output:

tomehb@tServer:~/Scripts$ ./test.sh
array: 1 2 3 4 5
values: 1[0]
random value: 3
tomehb@tServer:~/Scripts$


unsure why. Anyhow how stupid was I to not spot i had not reset the count to 0 everytime, after changing this it worked! I cant thank you enough :)

My script currently: *anyways how i could improve it???*


Code:

MEDWAYPATH="/usr/medway"
LOSTMSGPATH="/GBP/bin/lost-msg"

#Find GPRSS DIRS
GPRSS_LIST="`ls ${MEDWAYPATH} | grep GPRSS`"
if [ "$GPRSS_LIST" = "" ]
then
        echo "NO GPRSS Folders Found in $MEDWAYPATH"
        exit
else
        for list in ${GPRSS_LIST}
         do
                #Check for Too-old and Retry  messages
                MSGCHECK="`ls ${MEDWAYPATH}/${list}${LOSTMSGPATH} | grep Too-old | wc -l`"
                OLD_LIST="$OLD_LIST $MSGCHECK"
                MSGCHECK="`ls ${MEDWAYPATH}/${list}${LOSTMSGPATH} | grep Retry | wc -l`"
                RETRY_LIST="$RETRY_LIST $MSGCHECK"
        done
COUNT=0
        #Creates GPRSS ARRAY
        for list in ${GPRSS_LIST}
         do
                GPRSS[$COUNT]=${list}
                ((COUNT++))
         done

COUNT=0
        #Creates OLD MSG ARRAY
        for list in ${OLD_LIST}
         do
                OLDMSG[$COUNT]=${list}
                ((COUNT++))
         done

COUNT=0
        #Creates RETRY MSG ARRAY
        for list in ${RETRY_LIST}
         do
                RETRYMSG[$COUNT]=${list}
                ((COUNT++))
         done
fi

echo GPRSS Station List echo "---------------"
echo -e "No.\tGPRSS\t|\tOld MSGs\t|\tRetry MSGs\t|"

COUNT=0
#Lists amount of messages found by GPRSS Station for End User
for list in ${GPRSS_LIST}
        do
                echo -e $COUNT:  "\t$list\t|\t${OLDMSG[$COUNT]}\t\t|\t${RETRYMSG[$COUNT]}\t\t|"
                ((COUNT++))
done


echo Please make your Selection 1 to $COUNT:
read GPRSS
echo -e "You Selected \t$GPRSS"



Top
 Profile WWW  
 PostPosted: Thu May 07, 2009 2:45 am   

Joined: Thu Apr 23, 2009 7:47 am
Posts: 5
Location: Belgium
I think there are two typos in Erik's code:

The second for loop should be

Code:
for i in ${array[@]}; do

so with braces around 'array[@]'. $array is 1, $array[@] is 1[@], ${array[@]} is 1 2 3 4 5.

The line below should say

Code:
echo -n "${array[$x]} "

so the $ sign should be outside the braces, since {$array[$x]} is just 1[$x], where $x is 0 since the loop has only one iteration due to the previous typo.

So the code would be

Code:
#!/bin/bash
declare -a array
x=0
for i in $(seq 1 5); do
   array[$x]=$i
   ((x++))
done

x=0
# Print the array :)
echo "array: ${array[@]}"
# Print the array using a for loop instead of @. This reveals if the elements are in order.
echo -n "values: "
for i in ${array[@]}; do
   echo -n "${array[$x]} "
   ((x++))
done
echo
# Just test a random array element and see if it shows everything correctly
echo "random value: ${array[2]}"

and this works as Erik says.

Correct me if I'm wrong anywhere since I'm not used to working with arrays.

Greets,
Pieter


Top
 Profile  
 PostPosted: Thu May 07, 2009 2:52 am   

Joined: Mon Nov 17, 2008 7:25 am
Posts: 221
Yes, you're correct.

The braces are there to contain the "variable name".
$array[$x] would be $array [ $x ] since [ or ] is not a valid variable name character.

Sry I missed that little thing when I wrote it :P I blame it on work and nothing to try it out on :P

(ps. and my name is actually Fredrik and not Erik :P ds.)

Best regards
Fredrik Eriksson


Top
 Profile  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot] and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  


BashScripts | Promote Your Page Too
Powered by phpBB © 2011 phpBB Group
© 2003 - 2011 USA LINUX USERS GROUP