grep and delete
Anonymous Monk
created: 2006-01-20 23:19:49
hi everyone, I am trying to grep for word and delete the lines below the grepped word. Is there any way I could do that with seek and truncate? Thank you
Re: grep and delete
created: 2006-01-21 00:16:20
What kind of size of file are you talking about? (i.e. is it acceptable to slurp into memory)

one way is to just read a line at a time, and skip a chunk after your marker .. then write the whole thing back out..
my @lines;
open FILE, "<", "foo.txt";
while(  ){
  push @lines, $_;
  next unless /\byourWord\b/;
   for 1 .. 5;
}
close FILE;
open FILE, ">", "foo.txt";
print FILE, @lines;
close FILE;
Hmm.. that removes the 5 lines after each match .. re-reading OP it seems like it mightbe asking for just delete all the lines after the match ... using similar method:
my @lines;
open FILE, "<", "foo.txt";
while(  ){
  push @lines, $_;
  last if /\byourWord\b/;
}
close FILE;
open FILE, ">", "foo.txt";
print FILE, @lines;
close FILE;
Another option is [cpan://Tie::File] and a similar approach to above .. or start looping through the array, and just splice off everything after your word is found.
Re: grep and delete
created: 2006-01-21 00:22:45

This sounds like a good job for [cpan://Tie::File]. (the following is untested.)

use strict;
use warnings;

use Tie::File;

my @array;
tie @array, 'Tie::File', 'filename.txt' or die $!;

foreach ( 0 .. $#array ) {
    if( $array[$_] =~ /word/ ) {
        $#array = ( $_ < $#array ) ? $_ + 1 : $_;
        last;
    }
}

untie @array;

I often think of [cpan://Tie::Array] as mostly a novelty; not really something you would think of actually using. But I shouldn't think of it that way; it works, it's fast, and it makes some simple tasks even simpler.


Dave

Re: grep and delete
created: 2006-01-21 00:59:41

If the files aren't huge, or the word appears fairly early (a few hundred MB) in the file, then you can do this with a "one-liner" (wrapped for viewing; adjust quoting to your OS needs):

perl -e"BEGIN{$/=qq[the word or phrase]}" 
-ne"$n=tell ARGV; close ARGV; truncate $ARGV, $n" path\to\the\file

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
Re^2: grep and delete
created: 2006-01-21 01:25:14

Here's another one-liner that doesn't use a begin block:

perl -ni.bak -e "print; /word/ && last;" file.txt

When the thought came to me, I was surprised at how simple the solution turned out to be.


Dave

Re^3: grep and delete
created: 2006-01-21 02:48:30

That doesn't quite match the OPs stated requirements in that it will preserve the entire 'line', (which could be the entire file if this was a binary file), containing the keyword rather than truncating immediately after the keyword.

Has the advantage that it does matter how big the file, or how far into the file the truncation point is.

Has the disadvantage that it will consume more disc space rather than reducing it--if that was the original intent.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
Re^4: grep and delete
created: 2006-01-21 11:31:25

I think it does match the OP's spec: He said he wanted to truncate the line after the word, ie the next line and beyond. Maybe I'm misreading it, but that's how it sounded to me. And the fact that he is speaking of lines leads me to believe that he is dealing with a file that has line endings.


Dave

Re: grep and delete
created: 2006-01-21 06:35:36

You can, but these simpler tasks are easier to do with an editor unless the file is very large:

ed file <<<$'/\/+,$d\nw'
Alternately replace ed with ex, the same command will work with it.
Re^2: grep and delete
created: 2006-01-21 09:54:16
Hi everyone, WOW..!! I got so many replies.....I am trying to run the suggestions you gave...Now the problem I face is that...I am grepping an large xml file....(I dont have any hassles with memory ..) ..;-].....I have to grep for a word in the tail end of the file and remove the line below that word. thank u kindly,
Re^3: grep and delete
created: 2006-01-21 22:11:58
Hi , IS THERE ANY WAY OF GREPPING FOR THE WORD AND TRUNCATING ALL THE LINE BELOW INCLUDING THE WORD LINE? ANY SUGGESTIONS WILL BE A HELP AS I HAVE DEADLINE TO MEET. -
Re^4: grep and delete
created: 2006-01-22 02:02:43

Then youe deadline will meet you. Thanks for bring us good laugh.

perlmonks.org content © perlmonks.org and ambrus, Anonymous Monk, BrowserUk, davido, davidrw

prlmnks.org © 2006 edmund von der burg (eccles & toad)

v 0.03