0

So I need to write an awk script file that finds and prints the average field length of each record in a text document. The text document is this:

The quick brown fox jumped over the lazy dog's back.
The rain in Spain falls mainly on the plain.
The rain in Spain also falls on the mountains.

Right now, what I am using is this, in a script file:

{average = length($0)/NF
   print "Average field length for record: " average}

By doing "length($0)," it counts everything in the record. I tried doing something like length($1)+length($2)+length($3)+etc., but the records have different lengths and I can't account for that, especially since this is supposed to work with any length record.

The problem that I am having is that it counts whitespaces in between each field, and I don't want to count that. Currently, the numbers I am getting for each record are 5.2, 4.8, and 5.1, respectively. Is there a way to not count whitespaces?

In addition to this, I am required to find the average field length in the file as a whole. Again, I believe my awk script for this one is also counting whitespaces, which I do not want. This is my script file:

BEGIN{
        sum = 0
     }
{
     sum += length()
     sum = sum/NF
}
END{
     print "Average field length in file: " sum
     }

What modification must I make so that it does not count whitespaces, but only letters and punctuation, basically everything except for the whitespaces? As is, the number I get for the average of all fields in the text file is 5.7, which I do not believe is correct.

2
  • Are you aware of the {} formatting tool to format text as code? It would help in these situations, I'm sure.
    – Jeff Schaller
    Commented Nov 5, 2019 at 16:36
  • Perhaps pass the input through a tr to eliminate whitespace and then run awk over it?
    – Ketan
    Commented Nov 5, 2019 at 16:38

1 Answer 1

1

You can skip whitespace by relying on the default field separator and counting the fields’ sizes, as you suggest, accounting for varying numbers of fields by using the NF variable.

Thus for the averages per-record:

NF > 0 {
    linesum = 0
    for (i = 1; i <= NF; i++) linesum += length($i)
    print "Average field length for record: " linesum / NF
}

and for the whole file:

{
    for (i = 1; i <= NF; i++) sum += length($i)
    count += NF
}

END { if (count > 0) { print "Average field length in file: " (sum / count) } }

This also fixes the problem with calculating averages line by line.

With your example, this gives an average of 4.17857 (counting punctuation).

9
  • Ok, so I ran your script file through awk, and I also get 4.17, but it also prints out these numbers above that, like this: 4.4, 4.1, and 4.3. How do you get rid of those? Also, how would I modify that script file to make it work for my first problem of finding the individual record's averages?
    – John Mike
    Commented Nov 5, 2019 at 17:22
  • Those extra numbers are the individual records’ averages. Commented Nov 5, 2019 at 17:22
  • Ok, but I need to separate those. They are two different questions, and I am not sure how to separate them apart. How is it printing those averages if the only thing I see is "print Average field"
    – John Mike
    Commented Nov 5, 2019 at 17:25
  • print linesum / NF takes care of the individual records. I’ll update my answer to clarify things. Commented Nov 5, 2019 at 17:30
  • Ooooh, Okay. I got it, dude you are a freaking life saver. You are my favorite person right now. I actually have another question about the work I have, I will be uploading it soon, and will ask you about it as well, since you're obviously an expert.
    – John Mike
    Commented Nov 5, 2019 at 17:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .