A friend of mine uses a shareware utility for Windows that mirrors web sites so that you can browse them offline. This utility (unfortunately) adds some sort of banner to each downloaded page; the banner is delimited by two html comments. Here is an example:
<!-- inserted banner --> <TABLE> blah blah </TABLE> <!-- end of inserted banner -->
My friend wanted to remove this banner ... so I wrote a nice perl script for him. The script traverses the whole directory tree of the downloaded site and removes the html lines that create the banner from each page.
The first version of my script used a recursive procedure to go through all the files, read each line skipping those unwanted, and than wrote the file back.
Than I realized that I could use File::Find, so I started rewriting the script. In the meanwhile I was sort of enlightened: the .. operator appeared in my mind, and I realized I could use that too. So here is the second version of my script
use strict; use File::Find; die "usage $0 <dir>" unless (@ARGV == 1 && -d $ARGV[0]); find ( sub { return unless -f $_; open (FILE, "< $_") or warn "cannot read $_\n" and return; my @lines = grep {!(/inserted banner/i .. /end of inserted ban +ner/i)} <FILE>; close (FILE); open (FILE, "> $_") or warn "cannot write $_\n" and return; print FILE @lines; close (FILE); }, $ARGV[0] );
It works pretty well, and I'm quite happy with that ... and my friend is happy too :). Anyway in the process of continuous learning I started thinking of rewriting again the script to take advantage of -p command switch, and here is what I ended up with:
perl -MFile::Find -pi.bak -e "BEGIN {find sub {-f && push @ARGV, $File +::Find::name}, \".\"} if (/inserted banner/i) {while (<>) {s/.*// and last if /end of insert +ed banner/i;}}"
Moral: there is more than one way to do it :)
marcos

Replies are listed 'Best First'.
RE: Marcos' Meditation
by mdillon (Priest) on May 26, 2000 at 20:27 UTC
    how about this one-liner:

    perl -ne 'print unless /^<!-- inserted banner -->$/i .. /^<!-- end of inserted banner -->$/i'

    it should work as long as the delimiters are consistent. if not, the regexps can be enhanced slightly to accomodate some variety.

      You are right! And your solution is indeed much more elegant: I like it! I didn't know that the .. operator could be used in a scalar context in this way: now I've read again the perlop manpage and I understand the .. flip-flop like behavior :-) Thank you very much for your suggestion. Anyway I still need the -i switch to have the files edited in-place, and I still need the File::Find stuff to traverse the whole directory tree.