Dale:
The last section of each Xlib manpage is called "Related Commands"
(that is the argument of a .SH) and it's followed by a list of commands
(often 10 or 20) that are now in random order. It'd be more
useful and professional if they were alphabetized. Currently, commands
are separated by a comma after each one except the last, which has a
period.
The question is: could awk alphabetize these lists? We're talking
about a couple of hundred manpages. Again, don't bother if this is a
bigger job than it seems to someone who doesn't know what's involved.
Best to you and yours,
Lenny
To see what he is talking about,
a simplified version of an Xlib manpage is shown below:
.SH "Name"
XSubImage -- create a subimage from part of an image.
.
.
.
.SH "Related Commands"
XDestroyImage, XPutImage, XGetImage,
XCreateImage, XGetSubImage, XAddPixel,
XPutPixel, XGetPixel, ImageByteOrder.
You can see that the names of related commands appear
on several lines following the heading.
You can also see that they are in no particular order.
To sort the list of related commands is actually fairly
simple, given that we've already covered sorting. The structure
of the program is somewhat interesting, as we must read
several lines after matching the "Related Commands"
heading.
Looking at the input, it is obvious that the list of related
commands is the last section in the file.
All other lines except these we want to print as is.
The key is to match all lines from the heading
"Related Commands" to the end of the file.
Our script can consist of four rules, that match:
The "Related Commands" heading
The lines following that heading
All other lines
After all lines have been read (END)
Most of the "action" takes place in the END procedure.
That's where we sort and output the list of commands.
Here's the script:
# sorter.awk -- sort list of related commands
# requires sort.awk as function in separate file
BEGIN { relcmds = 0 }
#1 Match related commands; enable flag x
/\.SH "Related Commands"/ {
print
relcmds = 1
next
}
#2 Apply to lines following "Related Commands"
(relcmds == 1) {
commandList = commandList $0
}
#3 Print all other lines, as is.
(relcmds == 0) { print }
#4 now sort and output list of commands
END {
# remove leading spaces and final period.
gsub(/, */, ",", commandList)
gsub(/\. *$/, "", commandList)
# split list into array
sizeOfArray = split(commandList, comArray, ",")
# sort
sort(comArray, sizeOfArray)
# output elements
for (i = 1; i < sizeOfArray; i++)
printf("%s,\n", comArray[i])
printf("%s.\n", comArray[i])
}
When all lines of input have been read, the
END procedure is executed, and we know that our list of commands
is complete.
Before
splitting up the commands into fields, we remove any number
of spaces following a comma.
Next we remove the final period and any trailing spaces.
Finally, we create the array comArray using the split()
function.
We pass this array as an argument to the sort() function,
and then we print the sorted values.
This program generates the following output:
$ awk -f sorter.awk test
.SH "Name"
XSubImage -- create a subimage from part of an image.
.SH "Related Commands"
ImageByteOrder,
XAddPixel,
XCreateImage,
XDestroyImage,
XGetImage,
XGetPixel,
XGetSubImage,
XPutImage,
XPutPixel.
Once again, the virtue of calling a function to do the sort
versus writing or copying the code to do the same task is that
the function is a module that's been tested previously and
has a standard interface. That is, you know that it works and
you know how it works. When you come upon the same sort code
in the awk version, which uses different variable names, you
have to scan it to verify that it works the same way as other
versions. Even if you were to copy the lines into another program,
you would have to make changes to accommodate the new circumstances.
With a function, all you need to know is
what kind of arguments it expects and their calling sequence.
Using a function reduces the chance for error by
reducing the complexity of the problem that you are solving.
Because this script presumes that the sort() function
exists in a separate file, it must be invoked using
the multiple -f options:
$ awk -f sort.awk -f sorter.awk test
where the sort() function is defined in the file sort.awk.