gawk: Labels Program

1 
1 11.3.4 Printing Mailing Labels
1 ------------------------------
1 
1 Here is a "real-world"(1) program.  This script reads lists of names and
1 addresses and generates mailing labels.  Each page of labels has 20
1 labels on it, two across and 10 down.  The addresses are guaranteed to
1 be no more than five lines of data.  Each address is separated from the
1 next by a blank line.
1 
1    The basic idea is to read 20 labels' worth of data.  Each line of
1 each label is stored in the 'line' array.  The single rule takes care of
1 filling the 'line' array and printing the page when 20 labels have been
1 read.
1 
1    The 'BEGIN' rule simply sets 'RS' to the empty string, so that 'awk'
1 splits records at blank lines (⇒Records).  It sets 'MAXLINES' to
1 100, because 100 is the maximum number of lines on the page (20 * 5 =
1 100).
1 
1    Most of the work is done in the 'printpage()' function.  The label
1 lines are stored sequentially in the 'line' array.  But they have to
1 print horizontally: 'line[1]' next to 'line[6]', 'line[2]' next to
1 'line[7]', and so on.  Two loops accomplish this.  The outer loop,
1 controlled by 'i', steps through every 10 lines of data; this is each
1 row of labels.  The inner loop, controlled by 'j', goes through the
1 lines within the row.  As 'j' goes from 0 to 4, 'i+j' is the 'j'th line
1 in the row, and 'i+j+5' is the entry next to it.  The output ends up
1 looking something like this:
1 
1      line 1          line 6
1      line 2          line 7
1      line 3          line 8
1      line 4          line 9
1      line 5          line 10
1      ...
1 
1 The 'printf' format string '%-41s' left-aligns the data and prints it
1 within a fixed-width field.
1 
1    As a final note, an extra blank line is printed at lines 21 and 61,
1 to keep the output lined up on the labels.  This is dependent on the
1 particular brand of labels in use when the program was written.  You
1 will also note that there are two blank lines at the top and two blank
1 lines at the bottom.
1 
1    The 'END' rule arranges to flush the final page of labels; there may
1 not have been an even multiple of 20 labels in the data:
1 
1      # labels.awk --- print mailing labels
1 
1      # Each label is 5 lines of data that may have blank lines.
1      # The label sheets have 2 blank lines at the top and 2 at
1      # the bottom.
1 
1      BEGIN    { RS = "" ; MAXLINES = 100 }
1 
1      function printpage(    i, j)
1      {
1          if (Nlines <= 0)
1              return
1 
1          printf "\n\n"        # header
1 
1          for (i = 1; i <= Nlines; i += 10) {
1              if (i == 21 || i == 61)
1                  print ""
1              for (j = 0; j < 5; j++) {
1                  if (i + j > MAXLINES)
1                      break
1                  printf "   %-41s %s\n", line[i+j], line[i+j+5]
1              }
1              print ""
1          }
1 
1          printf "\n\n"        # footer
1 
1          delete line
1      }
1 
1      # main rule
1      {
1          if (Count >= 20) {
1              printpage()
1              Count = 0
1              Nlines = 0
1          }
1          n = split($0, a, "\n")
1          for (i = 1; i <= n; i++)
1              line[++Nlines] = a[i]
1          for (; i <= 5; i++)
1              line[++Nlines] = ""
1          Count++
1      }
1 
1      END {
1          printpage()
1      }
1 
1    ---------- Footnotes ----------
1 
1    (1) "Real world" is defined as "a program actually used to get
1 something done."
1