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

Hi I have few questions here.. I want to extract the lines starting with PLACED only if the sentence "HERE IS THE DATA" comes before it. How to do that because i dont want to extract all lines begin with PLACED but with the condition above. Thanks example: HERE IS THE DATA PLACED ABC; DO NOT ENTER PLACED BCD; HERE IS THE DATA PLACED ABC; WHO ARE U PLACED ABC;

Replies are listed 'Best First'.
Re: how to extract certain lines
by neilh (Pilgrim) on Oct 26, 2004 at 02:35 UTC
    I'm going to assume your data is thus:
    HERE IS THE DATA PLACED ABC; DO NOT ENTER PLACED BCD; HERE IS THE DATA PLACED ABC; WHO ARE U PLACED ABC;
    In order to extract where the phrase "HERE IS THE DATA PLACED" is in the start of the line do the following:

    while (<DATA>) { if (/\bHERE IS THE DATA PLACED/) { s/\bHERE IS THE DATA PLACED //; print $_; }else{ next; } } __DATA__ HERE IS THE DATA PLACED ABC; DO NOT ENTER PLACED BCD; HERE IS THE DATA PLACED ABC; WHO ARE U PLACED ABC; __OUTPUT__ ABC; ABC;

    Neil

    Update: Added print statement

      It sounds like you only want to match lines starting with PLACED if the "immediately preceding" line is "HERE IS THE DATA".

      This is not really a perl problem - it's a logic problem. I don't want to sound harsh, but if you were my student I wouldn't answer this question...

      There would be any number of possible solutions, but think about it this way:

      at any given time, you are asking two questions:

      q1) does the current line start with PLACED
      q2) does the previous line match "HERE IS THE DATA"

      so you basically want to look at the current line and the previous line at the same time.

      ... my $previous_line; while (my $current_line = <DATA>) { if ( $current_line =~ /^PLACED/ && $previous_line =~ /^HERE IS THE DATA$/ ) { print $current_line; } $previous_line = $current_line; }
      This can be optimised.

      If all you care about is seeing "HERE IS THE DATA" once, and then you want all lines starting with "PLACED" after it - just try thinking about your question another way around:

      q) have we ever seen a line that says "HERE IS THE DATA"?
      q) if we have, does the line start with PLACED?

      eg:

      ... my $seen_here_is_the_data; while (my $line = <DATA>) { $seen_here_is_the_data = 1 if $line =~ /^HERE IS THE DATA$/; if ( $seen_here_is_the_data && $previous_line =~ /^HERE IS THE DATA$/ ) { print $line; } }
      This can also be optimised.

      Update: FYI, the solution by neilh for the second case is simpler and the one I would use (and reccomend using) - I made mine as verbose as possible to try to help the seeker understand how to solve similar problems himself in the future.

Re: how to extract certain lines
by eyepopslikeamosquito (Archbishop) on Oct 26, 2004 at 02:52 UTC
    Please give an example of what you have tried so far. Your example test data is unclear; to clarify it, put <CODE> tags around your example code and example data.
      I want to extract from these data example: HERE IS THE DATA PLACED ABC; DO NOT ENTER PLACED BCD; HERE IS THE DATA PLACED ABC; WHO ARE U PLACED ABC;
        i type a few lines here but when i create, it becomes one long sentence?
Re: how to extract certain lines
by dee00zee (Novice) on Oct 26, 2004 at 04:04 UTC
    here is what im try to type
    example
    HERE IS THE DATA
    PLACED ABC;
    DO NOT ENTER
    PLACED BCD;
    HERE IS THE DATA
    PLACED ABC;
    WHO ARE U
    PLACED ABC;
    I want to extract the lines started with "PLACED..
    if the line "HERE IS THE DATA appear before it
      Try this

      while (<DATA>) { next unless /^HERE IS THE DATA/; my $line = <DATA>; print $line; } __DATA__ HERE IS THE DATA PLACED ABC; DO NOT ENTER PLACED BCD; HERE IS THE DATA PLACED ABC; WHO ARE U PLACED ABC; __OUTPUT__ PLACED ABC; PLACED ABC;

      Neil

        Thank you Neil..
        I still have questions here.
        Why do you use my before $line
        what is the function of my here?
        Thank you