lee@sq.sq.com (Liam R. E. Quin) (06/10/91)
I've been meaning to post this for ages... And then last week someone posted
something similar, so here goes!
This awk script (you need the "new" awk or nawk/gawk/mawk) reads a template
file (~/.newsorder), and sorts your .newsrc based on what it sees there.
Here's some of mine, with annottions. There's a smaller smaple in the
distribution itself.
# This file is read by newsorder as a template for sorting
# my .newsrc file.
sq.* # I want to see local newsgroups first...
comp.text.sgml # then SGML cos that's our business :-) :-)
comp.text*, !comp.text.tex
# all the rest of the text groups except the tex one
*.frp
*.magick # now some relaxation...
*.pagan
*.rpg
comp.font* # more work:
comp.text.tex
comp.archives
*windows*
*sources* !*.d !*.wanted # some sources groups
#new newsgroups:
/^.*:$/ # this pattern matches new newsgroups, so if
# rm adds them to my .newsrc, I can run newsorder
# and they all end up here where I see them.
# All other newsgroups go here, in the order in which they appear
# in my .newsrc...
: To unbundle, sh this file ---- cut here ---- cut here ---- snip! ---- ow!
echo x - Makefile 1>&2
sed 's/^X//' >Makefile <<'@@@End of Makefile'
X# Makefile for newsorder
X# Liam Quin, 1991
X# $Id: Makefile,v 1.6 91/02/07 17:58:40 lee Exp $
X
XBINDIR=/home/lee/scripts
XMAKE=make
XCLEAN=clean
X
XMANDIR=/usr/man/man1
XMANSECTION=1L
Xnewsorder: newsorder.sh
X cp newsorder.sh newsorder
X chmod 755 newsorder
X
Xinstall: newsorder
X -rm -f $(BINDIR)/newsorder
X cp newsorder $(BINDIR)/newsorder
X chmod 555 $(BINDIR)/newsorder
X # -rm -f $(MANDIR)/newsorder.${MANSECTION}
X # sed -e 's/ 1L / $(MANSECTION) /' newsorder.man \
X # > $(MANDIR)/newsorder.$(MANSECTION)
X $(MAKE) $(CLEAN)
X
Xclean:
X -rm -f newsorder .newsorder shar core *.o *.out
X @: delete files that are stored in RCS format and unchanged:
X -for i in * ; do \
X test -f RCS/$$i,v && rcsdiff $$i && rm $$i ; \
X done
X @: remind me that there are still files here...
X -/bin/ls -l
X
Xshar: Makefile newsorder.sh .newsorder
X -rm -f shar
X bundle $? > shar
X
XMakefile:: RCS/Makefile,v
X co -u Makefile
X
Xnewsorder.sh:: RCS/newsorder.sh,v
X co -u newsorder.sh
X
X.newsorder:: RCS/.newsorder,v
X co -u .newsorder
@@@End of Makefile
echo x - newsorder.man 1>&2
sed 's/^X//' >newsorder.man <<'@@@End of newsorder.man'
X.\" @(#)$Id: newsorder.man,v 1.5 91/02/07 17:49:03 lee Exp $
X.TH NEWSORDER 1L
X.SH NAME
Xnewsorder \- sort netnews .newsrc files by specified template
X.SH SYNOPSIS
X.B newsorder
X[
X.I inut-file
X]
X.SH DESCRIPTION
X.I newsorder
Xreads the file
X.I "$HOME/.newsorder"
Xand uses it as a basis to sort your
X.I \&.newsrc
Xfile.
XIf a filename option is given, this is sorted instead of your
X.I .newsrc
Xfile.
XThe filename \- is taken to be standard input.
X.PP
XEach line in the template file names a group or hierarchy of news-groups.
XFor example:
X.sp 0.5
X.RS
X# newsorder file for Liam
X.br
Xsq.* # SoftQuad local groups first
X.br
X*frp # anything that ends in frp
X.br
Xcomp.text* !comp.text.scribe # all the comp.text groups except one
X.br
Xcomp.lang*, !comp.lang.postscript, !*.intercal
X.sp 0.5
X.RE
X.LP
XNote that there is a difference between .* and * \- in particular,
X`comp.text.*' would not match the `comp.text' newsgroup.
X.PP
XAny lines in your
X.I \&.newsrc
Xfile that don't match any of the patterns will end up at the end of the new
Xfile, in the order in which they were found. Hence,
X.I \&newsorder
Xhas the effect of selecting certain groups and moving them to the front,
Xso that the news-readers will present them first.
X.PP
X.I Newsorder
Xwill prompt you asking whether or not to overwrite your
X.I \&.newsrc
Xfile. The resulting file is left in
X.IR ~/.newsrc-sorted ,
Xand optionally copied onto
X.I ~/.newsrc
Xitself.
XIn any case a copy of your original unsorted
X.I .newsrc
Xis made in
X.IR ~/.newsrc-unsorted .
X.SH AUTHOR
XLiam Quin, after an idea by Bob Gibson.
X.SH BUGS
XCould be more enthusiastic about looking for your
X.I \&.newsrc
Xfile.
X.br
XThe name
X.I newsorder
Xis probably a little long for System V users.
X.
X.\" $Log: newsorder.man,v $
X.\" Revision 1.5 91/02/07 17:49:03 lee
X.\" Fixed documentation of argument.
X.\"
X.\" Revision 1.4 91/02/07 17:26:35 lee
X.\" Put all filenames into italic, and changed the section from V to L.
X.\"
X.\" Revision 1.3 91/02/07 17:12:44 lee
X.\" Documented filename - as stdin and the backup of the .newsrc file.
X.\"
X.\" Revision 1.2 91/01/31 20:47:15 lee
X.\" fixed a typo in the BUGS section!
X.\"
X.\" Revision 1.1 91/01/31 20:45:47 lee
X.\" Initial revision
X.\"
X.\"
@@@End of newsorder.man
echo x - newsorder.sh 1>&2
sed 's/^X//' >newsorder.sh <<'@@@End of newsorder.sh'
X#! /bin/sh
X# $Id: newsorder.sh,v 1.7 91/04/23 15:43:27 lee Exp $
X# Liam Quin, 1991
X
X# newssort -- sort .newsrc ino order based on template
X
XTemplateFile="$HOME/.newsorder"
X
X# determine echo variant for prompts...
XN=-n; C=''; if test `echo 'hello\c'` = 'hello'; then N=''; C='\c'; fi
Xexport N C
X
XCMDNAME=${CMDNAME-"`basename $0`"}
Xexport CMDNAME
X
Xif test x"$1" = x""
Xthen
X InputFile="$HOME/.newsrc"
Xelif test -f "$1"
Xthen
X InputFile="$1"
Xelif test x"$1" = x"-"
Xthen
X InputFile="-"
Xelse
X echo "Usage: `basename $0` [input-file (default is $HOME/.newsrc)]" 1>&2
X exit 1
Xfi
X
Xcat "$InputFile" > $HOME/.newsrc-unsorted
X
Xcat "$InputFile" |
Xnawk '
X
XBEGIN {
X # FORMAT is how the lines are printed. The first number is the weighting
X # for sorting -- lower numbers go higher up in .newsrc -- the 2nd is the
X # input line number, so that the sort is stable.
X FORMAT = "%d %d %s\n"
X
X # read the template file
X while (getline < "'"$TemplateFile"'") {
X gsub(/[ ]*#.*$/, "") # delete comments
X if ($0 ~ /^[ ]*$/) {
X # ignore blank lines
X continue
X }
X if ($0 ~ /^\/.*\//) {
X Line = $0
X sub(/^\//, "")
X sub(/\/[^\/]*$/, "")
X Patterns[++PatCount] = $0
X MatchField[PatCount] = 0 # match on the entire line
X $0 = Line
X sub(/^\/.*\//, "") # to allow (literal) inclusions and exclusions
X } else {
X gsub(/,/, " ") # turn , into space
X gsub(/[.]/, "\\.")
X gsub(/[*]/, ".*")
X Patterns[++PatCount] = "^" $1 "[:!]*$"
X MatchField[PatCount] = 1 # match on the newsgroup name only
X }
X # Uncommment the next 2 lines to see the patterns...
X printf "PatCount %d Pattern /%s/\n",
X PatCount, Patterns[PatCount] > "/dev/tty"
X
X # deal with exclusions:
X
X for (i = 2; i <= NF; i++) {
X if ($i ~ /^!/) {
X sub(/[!]/, "", $i)
X j = ++HasExclusions[PatCount]
X Exclusions[PatCount,j] = "^" $i "[:!]*$"
X } else {
X printf "'"${CMDNAME}"': '"${TemplateFile}"': %d: %s",PatCount,
X "Exclusion patterns mst start with a !\n" | "cat 1>&2"
X exit 1
X }
X }
X }
X}
X
X# Now go through .newsrc and assign a priority to each line
X
X/^[ ]*$/ { next }
X/^[oO]ptions:/ { printf FORMAT, 0, NR, $0; next }
X
X{
X # Pattern 0 is used for the Options: line which must come first,
X # so we loop from 1 to PatCount...
X for (i = 1; i <= PatCount; i++) {
X if ($(MatchField[i]) ~ Patterns[i]) {
X Wanted = 1
X if (i in HasExclusions) {
X # see if it matches any of the exclusion patterns:
X for (j = 1; j <= HasExclusions[i]; j++) {
X if ($1 ~ Exclusions[i,j]) {
X # Aha! Not wanted here...
X Wanted = 0
X break
X }
X }
X }
X if (Wanted) {
X printf FORMAT, i, NR, $0
X if (!(i in Matched)) {
X PatUsedCount++ # Used a pattern for the first time
X }
X Matched[i]++
X next
X }
X }
X }
X printf FORMAT, i, NR, $0
X next
X}
X
XEND {
X # display information about which patterns worked:
X printf "'"${CMDNAME}"': Used %d out of %d patterns from template \"%s\"\n",
X PatUsedCount, PatCount, "'"${TemplateFile}"'" | "cat 1>&2"
X for (i = 1; i <= PatCount; i++) {
X if (!(i in Matched)) {
X printf "'"$0"': Unused: %d: /%s/\n",
X i, Patterns[i] | "cat 1>&2"
X }
X }
X}
X' |sort +0n +1n |sed -e 's/^[0-9][0-9]* [0-9][0-9]* //' > $HOME/.newsrc-sorted
X
Xwait # in case the cat hasn't finished from within awk
X
Xecho $N "Overwrite $HOME/.newsrc with sorted version? $C" 1>&2
Xread ans
X
Xcase "$ans" in
X[yY]*) cp $HOME/.newsrc-sorted $HOME/.newsrc || exit 1 ;;
X*) echo "Sorted output left in $HOME/.newsrc-sorted" 1>&2 ;;
Xesac
X
Xexit $?
X
X#
X# $Log: newsorder.sh,v $
X# Revision 1.7 91/04/23 15:43:27 lee
X# Now recognises a pattern like /.../ in the 1st field as an expression to
X# match over the entire input line, so you can use /:$/ to match new
X# newsgroups.
X#
X# Revision 1.6 91/02/07 17:09:55 lee
X# Improved the arguments to sort after Bob Gibson (rgj@sq.com) found a bug
X#
X# Revision 1.5 91/01/31 20:44:35 lee
X# Improved error-checking and replaced "cp -i" with an explicit test.
X#
X# Revision 1.4 91/01/30 19:28:01 lee
X# Improved error message slightly.
X#
X# Revision 1.3 91/01/30 19:25:47 lee
X# Added exclusion patterns, so you can do
X# comp.text*, !comp.text.tex
X# if you like.
X#
X# Comments (introduced with a #) and blank lines are now ignored.
X#
X# Revision 1.2 91/01/30 16:49:38 lee
X# Added summary statistics.
X#
X# Revision 1.1 91/01/29 23:10:45 lee
X# Initial revision
X#
X#
@@@End of newsorder.sh
echo End of archive
exit 0
--
Liam Quin, lee@sq.com, SoftQuad, Toronto, +1 416 963 8337
the barefoot programmer