# Thread: newbie to bourne shell question

1. Registered User
Join Date
Jan 2004
Posts
4

## Unanswered: newbie to bourne shell question

Im stuck on a file reading question. Ive got a file that looks like this:
1 5 4 2 3
6 7 8 9 9
1 4 5 6 3
8 7 4 1 5
2 5 8 3 9
3 6 5 3 4
I want to calculate the average for rows and columns.
Ive got a while loop that looks like this :

do
number=`echo "\$line" | cut -c1` #or i could use -f1 and it will still work
sum=`expr \$number + \$sum`
done < \$1
problem here is that this only gives me the average of the first column ( 1+6+1+8+2+3)/6 where I have to manually divide it by six ( my second problem).

1)How can I make it compute all the averages of the other columns?
2)I have no idea how to do the same with the rows. Also is there some way to automatically detect the number of rows and the number of columns and set those values to variables so I can calculate the averages.

Thanks

2. Registered User
Join Date
Jul 2003
Location
Edinburgh
Posts
35

## Re: newbie to bourne shell question

the awk utility has all the functionality you require and should be available in your installation. You are making a rod for your own back if you want to write it in the shell itself. The awk language syntax is similar to C and splits the input file into columns automatically.

Place the following text in a script, and you can determine the averages "./script.awk file.dat"

#!/path/to/awk -f
{
THISROW=0;
NROWS+=1;
NCOLS=NF;
for (i=1; i<=NF; ++i)
{
COL[i]+=\$i;
THISROW+=\$i;
}
printf "%s%s%5.2f\n", \$0, " row average: ", THISROW/NF;
}

END {
print "-----------------";
printf "%s", "Column averages: "
for (i=1; i<=NCOLS; ++i)
{
printf "%5.2f ", COL[i]/NROWS;
}
printf "\n";
}
Last edited by chillies; 01-18-04 at 08:20.

3. Registered User
Join Date
Jan 2004
Posts
4
You see. Im not supposed to use the awk utitility. Ive heard of it and it sounded real easy to use. Thank you very much for the reply though. Do you have any other ideas other than using the awk util. Thanks for your help.

4. Registered User
Join Date
Jul 2003
Location
Edinburgh
Posts
35

## more questions

Which shell are you using? bash allows variable arrays so you can use a similar method to the previous example. And why not use awk? Are you doing a programming assignment?

Which other utilities can be used? Can one use sed? I see you used expr and cut in the original post.

5. Registered User
Join Date
Jan 2004
Posts
4
Im doing part of a programming assignment and Im supposed to use bash. The utilities im supposed to use are read, expr, cut, head, tail, wc, and sort. Thanks for the reply

6. Registered User
Join Date
Jul 2003
Location
Edinburgh
Posts
35
Here you go ... it does the column averages of stdin and there's enough in there to allow you to sort out the row averages.

I'm using GNU bash, version 2.05b.0(1)-release (i686-pc-cygwin) which seems to have wierd behaviour in read when the input file doesn't end with a newline. That's why there's the line with the -z test.

I'm sad that you can't use dc, as it's quite nice to use a stack-based language. This script with expr uses integer arithmetic and rounds down.

One reason I'm answering posts in this forum is that I've volunteered to give a bash demo/tutorial for the local linux user group, and I'm trying to get some revision. I'd appreciate if you could post other questions from the course so I can gauge the topics I'd have to cover. And say which level the course is, too. Thanks.

#!/path/to/bash

declare -a COLSUM

dbforums () {
let LINES=\$LINES+1
[ \$LINES == 1 ] && NCOLS=\${#COL[*]}
for (( i=0; i<\$NCOLS; ++i )); do
let COLSUM[\$i]+=COL[\$i]
done
}

LINES=0
do
dbforums
done
[ -z "\${COL[0]}" ] || dbforums

for (( i=0; i<NCOLS; ++i ))
do
# dc -e "2 k \${COLSUM[\$i]} \$LINES / n [ ] n"
echo -n "\$(expr \${COLSUM[\$i]} / \$LINES) "
done
echo

7. Registered User
Join Date
Jan 2004
Posts
4
I also forgot to tell you that we are supposed to start the script with: #!/bin/sh.

8. Registered User
Join Date
Jul 2003
Location
Edinburgh
Posts
35
Originally posted by WhiteTree
I also forgot to tell you that we are supposed to start the script with: #!/bin/sh.
Hmmm ... Usually the # character indicates the remainder of a line is a comment, except when it's the first character on the first line and is followed by an exclamation mark. In that case, the kernel uses the remainder of the line as the interpreter (and any flags) to run. #!/path/to/bash is a shorthand I've used that you should replace with the path to your bash interpreter.

If you're on linux /bin/sh is usually linked to to bash, but if you actually have to use the Bourne shell (/bin/sh) then you won't have arrays and you'll have to find another solution.

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•