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

This one has had me stuck for hours.

I have a file that I have read into a scalar and I want to delete every line that does NOT begin with two dashes (--).

Can someone tell me a trick to do that? Also, for my own learning, suppose I wanted to delete every line that does NOT begin with two dashes EXCEPT for empty lines (\n only).

Thank you for your help.

Replies are listed 'Best First'.
Re: simple (in theory) regexp question
by japhy (Canon) on Apr 14, 2002 at 18:05 UTC
    Ok, here we go: $contents =~ s/^(?!--|\n).*\n//mg; That looks ahead for two dashes or a newline at the start of every "line". If it DOES NOT FIND THEM, it matches the rest of the line and replaces it with nothing. The /m modifier is necessary so that ^ matches at the beginning of "lines".

    _____________________________________________________
    Jeff[japhy]Pinyan: Perl, regex, and perl hacker, who'd like a (from-home) job
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

Re: simple (in theory) regexp question
by strat (Canon) on Apr 14, 2002 at 19:06 UTC
    There is more than one wayss to do it...

    e.g.

    sub ReadFile { my ($filename) = @_; local $/; # undef $/ for slurping in whole file open (FILE, $filename) or die "Error in reading from $filename: $!\n"; my $content = <FILE>; close (FILE); $content =~ s/^(?!--|\n).*\n//mg; # => see japhy's answer return ($content); } # ReadFile
    or reading into arraymode and then building scalar (might be faster, but haven't tested it).
    sub ReadFile { my ($filename) = @_; open (FILE, $filename) or die "Error in reading from $filename: $!\n"; my $content = ""; while (<FILE>){ if ($_ eq "\n" # if empty line or /^\-\-/){ # or -- at the beginning $content .= $_; # then append } # if } # while close (FILE); return ($content); } # ReadFile

    Best regards,
    perl -le "s==*F=e=>y~\*martinF~stronat~=>s~[^\w]~~g=>chop,print"

Re: simple (in theory) regexp question
by christina_sampson (Novice) on Apr 14, 2002 at 19:37 UTC
    (In the spirit of TIMTOWDY.) Or if you want to be sloppy and short:

    % perl -i -pe 's/^--(.*)\n//g' your_file

    update: Please see Juerd's response below for the proper response to the author's question.

    christina (not that I want to be sloppy and short)
      % perl -i -pe 's/^--(.*)\n//g' your_file

      hm. that would delete every line that starts with two dashes (the original poster wanted to keep those lines).

      Update: removed the 'm' modifier bit, since the code was acting on the file, instead of acting on the 'slurped' file.

      hope this helps,

        . also, you want the 'm' modifier for the s/// operator, since the whole file is read into a scalar

        Which is not true with -pe without an alternative line ending. The file is read line-by-line.

        the original poster wanted to keep those lines

        So you're doing the exact opposite. I'm sure that'll help. Sigh. How about:

        perl -i -pe'$_ = "" unless /^--/ or !/\S/'
        which does what the original poster wants (If I understood correctly).

        Update - This was meant to be a reply to the parent of the node I replied to. This node's parent didn't have the code indented in a way I recognised as being a quote, and I didn't view the message in its context when I replied. To everyone who cites: please use <blockquote>. I use <p><blockquote><em> quote </em></blockquote></p><p> answer </p>, and even have that in my signature for ease of use.

        - Yes, I reinvent wheels.
        - Spam: Visit eurotraQ.
        

Re: simple (in theory) regexp question
by mrbbking (Hermit) on Apr 15, 2002 at 02:27 UTC
    How about this?
    #!/usr/bin/perl -w use strict; my $file_contents; while( <DATA> ){ next unless ( /^--/ || /^$/ ); $file_contents .= $_; } print $file_contents; __DATA__ --keep me delete me -- don't not throw this one out. -- delete every line that does NOT begin with two dashes... -- is the same as keep every line that begins with two dashes
    --HTH
    s!!password!;y?sordid?binger?; y.paw.mrk.;;print chr 0x5b ;;; print;print chr(0x5b+0x2);;;;;
•Re: simple (in theory) regexp question
by merlyn (Sage) on Apr 15, 2002 at 14:20 UTC