#! /usr/bin/gawk -f # Last edited on 2000-02-02 02:27:56 by stolfi BEGIN { usage = ( ARGV[0] "\\\n" \ " [-v columns=COLUMNS | -v pagewidth=PAGEWIDTH] \\\n" \ " [-v colwidth=COLWIDTH] \\\n" \ " [-v lines=LINES] \\\n" \ " [-v sep='string'] \\\n" \ " [-v filler='string'] \\\n" \ " [-v left='string'] [-v right='string'] \\\n" \ " [-v head='string'] [-v foot='string'] \\\n" \ " < INFILE > OUTFILE" \ ); # Like "pr" (bleech!) but does the right thing. Prints INFILE in # COLUMNS columns, LINES lines per page. # The columns in the last page are always balanced. If LINES is 0 or # omitted, it defaults to infinity, i.e. there will be a single page # with just enough lines to fit balanced columns. Otherwise # all pages (even the last one) will have LINES lines of data. # The FILLER string is used to complete short columns, and, # if LINES > 0, to complete the last page. It defaults to empty. # If COLWIDTH is not specified, it defaults to 0. The actual width # of each column is the maximum between COLWIDTH, the length of # the the widest line in INFILE, and the length of the FILLER string. # If PAGEWIDTH and COLUMNS are not specified or zero, they default to # infinity. At least one of them must be specified. In any case, # COLUMNS will be reduced as needed so that the output lines will not # exceed the specified PAGEWIDTH. On the other hand, at least # one column will be printed, even if the PAGEWIDTH gets exceeded. abort = -1; if (columns == "") { columns = 0; } else if ((columns !~ /^[0-9]+$/) || (columns < 0)) { arg_error("bad \"columns\""); } if (pagewidth == "") { pagewidth = 0; } else if ((pagewidth !~ /^[0-9]+$/) || (pagewidth < 0)) { arg_error("bad \"pagewidth\""); } if ((pagewidth == 0) && (columns == 0)) { arg_error("you must specify \"pagewidth\" or \"columns\""); } if (lines == "") { lines = 0; } else if ((lines !~ /^[0-9]+$/) || (lines < 0)) { arg_error("bad \"lines\""); } if (colwidth == "") { colwidth = 0; } else if ( colwidth !~ /^[0-9]+$/ ) { arg_error("bad \"colwidth\""); } nrecs = 0; maxwidth = length(filler); if (colwidth > maxwidth) { maxwidth = colwidth; } split("", rec); } # Gobble up lines (abort >= 0) { exit abort; } // { rec[nrecs] = $0; nrecs++; m = length($0); if (m > maxwidth) { maxwidth = m; maxline = $0; } } END { if (abort >= 0) { exit abort; } # printf "maxwidth = %d maxline = [%s]\n", maxwidth, maxline; # Adjust number of columns to fit: if (columns == 0) { columns = nrecs; } cw = maxwidth + length(sep); if ((cw > 0) && (pagewidth != 0)) { avail = pagewidth - length(left) - length(right); maxcols = int((avail + length(sep)) / cw); if (maxcols < columns) { columns = maxcols; } } if (columns == 0) { columns = 1; } # Adjust page size and number of pages: if (lines > 0) { nrecspp = lines*columns; npages = int((nrecs + nrecspp - 1)/ nrecspp); } else { nrecspp = nrecs; lines = int((nrecspp + columns - 1) / columns); npages = 1; } # Print it: for (ip = 0; ip < npages; ip++) { if (head != "") { printf "%s\n", head; } # Compute range and number of records in this page: ini = ip*nrecspp; fin = ini + nrecspp; if (fin > nrecs) { fin = nrecs + 1;} nr = (fin - ini); # Compute number of records per column: nrpc = int((nr + columns - 1) / columns); for (jl = 0; jl < lines; jl++) { printf "%s", left; for (kc = 0; kc < columns; kc++) { if (kc > 0) { printf "%s", sep; } if (jl < nrpc) { ir = ip*nrecspp + kc*nrpc + jl; r = ( ir < nrecs ? rec[ir] : filler ); } else { r = filler; } printf "%-*s", maxwidth, r; } printf "%s\n", right; } if (foot != "") { printf "%s\n", foot; } } } function arg_error(msg) { printf "*** %s\n", msg > "/dev/stderr"; abort = 1; exit abort; }