views:

1353

answers:

2

Hi,

I want to write a generic awk script that can take as input a file and a field number (in that file) and give me the average value of that field in that file. I would use it something like this:

bash$ avg.awk 3 input.file
22
bash$ avg.awk 4 input.file
2001

Of course, I can write the script if I know which field (e.g., $3) I am going to average beforehand. That would be something like this:

//{tot+=$3; count++}
END{
    print tot/count;
}

But I want to be able to change the field I want to average through a command line option. Is that possible? Thanks!

+4  A: 
{ tot += $field; count++ }
END { print tot/count }

call like awk -v field=3 -f avg.awk input.file

Steven Huwig
You can use NR to avoid having a count variable: {tot+=$f} END { print tot/NR}
ire_and_curses
... assuming the OP doesn't actually want to filter out headers or skip records. :)
Steven Huwig
Thanks, it definitely works! The other answer makes command line easier to use though :)
allrite
+3  A: 

This one will do what you want:

$ cat avg.awk
#!/usr/bin/env awk -f
# Calculate average, syntax: avg.awk field-number file
BEGIN { field = ARGV[1]; ARGV[1] = "" }
{ sum += $field }
END { print sum / NR }

$ cat data
1 5 7
3 6 5
8 4 6

$ avg.awk 1 data
4

$ avg.awk 2 data
5

$ avg.awk 3 data
6
Hai Vu
I couldn't use env like the way you described. For now, I have just put the real path to awk. It works though. Thanks!
allrite
Using /usr/bin/env is my way to cope with the fact that different systems install awk in different places. You might want to issue a 'which env' from the command prompt to find out where env is in your system.
Hai Vu
/usr/bin/env: awk -f: No such file or directoryThis is the message I am getting. env is in /usr/bin/env. Although you have solved my initial problem, would love to learn how env can be used.
allrite
You are correct: it does not work. I copy that line from my Tcl scripts:#!/usr/bin/env tclshThat line works for tclsh, but it does not work for awk and I am baffled.
Hai Vu