newsorder -- re-order your .newsrc by preference

Liam R. E. Quin lee at sq.sq.com
Mon Jun 10 14:01:58 AEST 1991


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 at 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 at sq.com, SoftQuad, Toronto, +1 416 963 8337
the barefoot programmer




More information about the Alt.sources mailing list