[olug] Grep Sed Question

Christopher Cashell topher-olug at zyp.org
Sat Jun 16 10:17:59 UTC 2007


At Fri, 15 Jun 07, Unidentified Flying Banana Stan Coleman, said:

> I have a project where I want to remove a specific line from a text
> file. Piece of cake I've done that many times. Here is the twist I
> want to remove the specific line AND the line just prior to the
> specific line. Any thoughts?

I think that because of the line oriented nature of sed and grep, this
will be difficult, if not impossible to accomplish with them.  By the
time they know that you've reached the match line, they've already
printed out the preceding line.

My suggestion would be to use awk or perl, provided there isn't some
special restriction or requirement for grep or sed.

I threw together a quick example in perl, which I've included here.
It's only been tested against one little sample file I threw together,
but it seems to work.  Note that you will have to change /tag/ to
whatever regular expression will match the line you want removed.

It's currently setup to act as a filter, such as:

  rem_line+pre.pl <input_file >output_file

Also note that I haven't written a whole lot of perl lately, so bugs are
entirely likely.  If anyone happens to see an error, please let me know.

-- 
| Christopher
+------------------------------------------------+
| Here I stand.  I can do no other.              |
+------------------------------------------------+


------------------CUT HERE------------------------

#!/usr/bin/perl
# vim: ts=3 sw=3 et sm ai smd sc bg=dark

use strict;
use warnings;

my $previous;
my $skip;
my $match = 'tag'; # Regex to match line to remove
$_ = ""; # We need to pre-initialize this so our until loop works

# We need to grab the first line here and set $previous to it since
# we're buffering 1 line to give us the ability to skip the line
# preceding our match.
#$_ = <STDIN>;
until (not /$match/) {
   $_ = <STDIN>;
}
$previous = $_;

while (<STDIN>) {
   if (/$match/) {
      # Don't print anything, and set $skip so we skip the next one.
      $skip = "yes";
   }
   else {
      unless ($skip) {
         print $previous;
      }
      undef $skip;
   }
   $previous = $_;
}

# We're operating one line behind, so now we need to print the final
# line, provided we're not skipping.
unless ($skip) { print $previous }




More information about the OLUG mailing list