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