skyler has asked for the wisdom of the Perl Monks concerning the following question:

How are you monks!! I hope that you give me some ideas in reference to a program which I think writing to automate a process. I want to read a file that contains many lines; I'm suposse to check line by line to see if it has a pattern for example : qw (12345 23453 23445 34445) If I find the number string, I need to suppress the line for printing to a file. I figure I need to use a buffer to store those lines that do not have a matching number. I'll appreciate your help and suggestions. I know that it may sound easy but I don't know how to use buffers. Thanks

Replies are listed 'Best First'.
Re: Finding a string within a string
by tachyon (Chancellor) on Apr 10, 2003 at 05:01 UTC

    One line is all it takes. Here I suppress the lines that match foo by only printing the line if it does not. Redirect the output from STDOUT to a file out.txt and you are done. Use ' instead of " on *nix

    C:\>type data.txt foo bar foo bar foo foo C:\>perl -n -e "m/foo/ or print" data.txt > out.txt C:\>type out.txt bar bar C:\>

    To match lots of differect stuff you would just match m/this|that|other/ If you wantit long hand it might look like:

    #!/usr/bin/perl -w use strict; $ARGV[0] or die "Useage ./$0 file_to_process > output.file\n"; my @finds = qw( this that other ); my $finds_re = join '|', map { quotemeta }@finds; $finds_re = qr/$finds_re/; open F, $ARGV[0] or die $!; while(<F>) { next if m/$finds_re/; print; } close F;

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

      Tachyon I appreciate your help. Here is my code. This code only suppresses a block, how could I modify this code to instead of suppressing a block it suppress a line. Here is the code:
      #!perl -w my ($fs, $cs, $rs, $ec, $ss); setdelimiters('|^~\&'); sub setdelimiters { ($fs, $cs, $rs, $ec, $ss) = map {quotemeta} split //, $_[0]; } use strict; my $buffer=""; my $suppress = 0; my @field; my %newblock; my %partofblock; my %skipaccount; $skipaccount{$_} = 1 for qw(77403 77404 77406 77407 77408 77409 77411 +77412 77413 77414 77416 77418); my $infile = 'c:/testfile.txt'; my $outfile = 'c:/idxfile.txt'; open IN, "<$infile" or die "Couldn't open $infile, $!"; open OUT,">$outfile" or die "Couldn't open $outfile, $!"; $newblock{$_} = 1 for qw(MSH); $partofblock{$_} = 1 for qw(EVN PID FT1); while (<IN>) { chomp(); if (/^(MSH)(.....)/) { setdelimiters($2); } @field = split /$fs/; if ($newblock{$field[0]}) { processbuffer(); } elsif (!$partofblock{$field[0]}) { print STDERR "Possible error: segment=$field[0] line $.\n"; } if ($field[0] eq "FT1") { $suppress = 1 if $skipaccount{$field[7]}; } $buffer .= "$_\n"; } processbuffer(); sub processbuffer { print OUT $buffer unless $suppress; $buffer=""; $suppress = 0; }
        perl -n -e "m/77403|77404|77406|77407|77408|77409|77411|77412|77413|77 +414|77416|77418/ or print" infile.txt > outfile.txt

        Otherwise you will need to be more exact ie specify what the data looks like and what your code is supposed to do. It is far from clear in what you asked and the code you posted :-)

        cheers

        tachyon

        s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

        Is there any logic to your indentation style, or do you just hit tab at random? :)

        Consistent indentation makes code much easier to read. If code is easy to read, you'll get more useful answers because more people will bother to try to understand.

        Juerd
        - http://juerd.nl/
        - spamcollector_perlmonks@juerd.nl (do not use).
        

Re: Finding a string within a string
by zenn (Sexton) on Apr 10, 2003 at 13:38 UTC
    Two solutions : 1) print to another file and move it to the first after you close it

    2) put the whole content in a @buffer, and save it to the file after you finish.

    In your case I would prefer the first. The second one is better when you want to process the contents another time before printing/saving

    Just as an example I will show a snippet of a backup script I have. The first part collects the output messages of a program hilighting the interesting lines
    . The second is the function that sends that as an email.
    {...} foreach(@fsystem){ $fs=$_; print "Backup do $mountpoint{$fs} ($fs)\n"; open (FS,"/sbin/dump $param \/dev/$mountpoint{$fs} 2>&1 |"); push(@messages,("\nBackup de /dev/$mountpoint{$fs} ($fs)\n\n\n +")); while($linha=<FS>){ push(@messages,$linha); if ($linha=~ /DUMP IS DONE/){ print color 'green'; } if ($linha=~/error/)&&($linha=~/ERROR/)&&($linha=~/Error/){ print color 'red'; } print $linha; print color 'reset'; } close(FS); } {...} sub EnviaMail(){ $smtp = Net::SMTP->new('256.256.256.256'); $smtp->mail($sender); $smtp->to($resp); $smtp->data(); $smtp->datasend("To: $resp\n"); $smtp->datasend("From: \"Backup $localhost\" \<$sender>\n"); $smtp->datasend("Subject: Backup $localhost\n"); $smtp->datasend("\n"); foreach $linha (@messages) { $smtp->datasend($linha); } $smtp->dataend(); $smtp->quit; }
    Zenn