AWK has been ported to the QL by Peter Tillier and is a Unix language that is used for all sorts of list processing tasks. The name comes from the three writers of the language; Aho, Weinberger, and Kernighan.
AWK works very similar to grep. For each line of input, it searches for a given pattern. If the pattern matches, then an action is performed. If there is no search pattern, then it is assumed to match and the action is performed. This is the formal definition of what AWK does, in reality, the code looks a lot like other languages, and each line usually does not have a pattern and is therefore executed. How this all works will become clearer as you read the code below.
To give an example of how to use AWK, here is something that I’m using AWK to do. I keep a list of people that get the QHJ via e-mail. In the list is the persons last name, first name and e-mail address. From this list I want to generate a e-mail address only list, for sending an issue, and a list of people, sorted by last name.
I’ve created a text file with each field seperated by colons and each record is a seperate line. Here is an example file:
test_data:
Andrews:Bob:bob@mail.com
Johnson:Ralph:rj@newmail.com
Smith:John:john@oldmail.com
Wilson:Ted:trw@mail.com
The first AWK script will print out only the 3rd field from each line. Here it is:
rep1_awk:
{
FS = ":";
print $3;
}
And the output is:
bob@mail.com rj@newmail.com john@oldmail.com trw@mail.com
Basically all the script does is this: for each line, change the Field Seperator to be a colon and then print out field #3.
The second report is a little more complicated. It will have a header, then the e-mail addreses, and then a footer giving a count of the e-mail addresses. The BEGIN block will only be executed at the beginning of a program, before any work is done on the input file. I’m using the BEGIN block to print out a header for the report. There is also an END block, which will only be executed at the end of the program. Here is the 2nd AWK script:
rep2_awk:
BEGIN {
print " Name E-Mail Address"
print "---------------------------------"
}
{
FS = ":"
printf("%6s %10s %s\n",$2,$1,$3)
}
Here is the output:
Name E-Mail Address --------------------------------- Bob Andrews bob@mail.com Ralph Johnson rj@newmail.com John Smith john@oldmail.com Ted Wilson trw@mail.com
This time I’ve decided to use a printf statement, which is very similar to the C version of printf. The problem though is that the output of the names is right justified and there is too much space between the first and last name. I want one space between the first and last name. Here is a 3rd AWK script that uses a regular print instead of a printf and gives me what I want:
rep3_awk:
BEGIN {
print " Name E-Mail Address"
print "-----------------------------------"
count = 0
}
{
FS = ":"
print $2,$1,"\t",$3
count = count + 1
}
END {
print "-----------------------------------"
print " Total Addresses = ",count
}
Here is the output:
Name E-Mail Address ----------------------------------- Bob Andrews bob@mail.com Ralph Johnson rj@newmail.com John Smith john@oldmail.com Ted Wilson trw@mail.com ----------------------------------- Total Addresses = 4
Now if I had to write this program in SuperBasic, I would first have to write a section that splits out the individual fields into different string variables. With AWK it’s automatic and very easy to do.