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

Am also a new perl dude. I have a large report that lists good and bad urls in our library catalog. e.g.
Filename: url Title: Mary moo-cow 856 invalid url Title: the mechanics 856 valid url
How do I match the word title and invalid and then print only the lines that contain these words and not the lines that don't. I don't want the lines that contain valid. As the report is now, I have to scroll through 500 some pages and look at each entry to determine which record has in invalid url.

2005-01-12 Janitored by Arunbear - added code tags, to preserve formatting

Replies are listed 'Best First'.
Re: match word on line - match word on another line - print lines
by holli (Abbot) on Jan 12, 2005 at 11:17 UTC
    use strict; my $title; while ( <DATA> ) { $title = $_ if /^Title: .+$/; print $title, $_ if /^856 invalid/; } close IN; __DATA__ Title: Mary moo-cow 856 invalid url Title: the mechanics 856 valid url Title: Terminator 2 856 invalid url
Re: match word on line - match word on another line - print lines
by perlsen (Chaplain) on Jan 12, 2005 at 11:27 UTC

    Hai just try this

    $str='url Title: Mary moo-cow 856 invalid url Title: the mechanics 856 valid url Title: Mary moo-cow 858 invalid'; my @string =split/\n/, $str; my @arr=(); for (@string) { if ($_ =~m#url Title:\s((.+?)\s(\d+)) invalid#gsi) { push(@arr,$1); } } print "$_\n" for @arr;

    output:

    Mary moo-cow 856

    Mary moo-cow 858

Re: match word on line - match word on another line - print lines
by gube (Parson) on Jan 12, 2005 at 11:41 UTC

    Hi, just try this with created file

    open(IN, "d:\\temp.txt") || die "Cannot open file"; while (<IN>) { if ($_ =~ m#url Title: (.*?) invalid#gsi) { push(@arr, $1); } } $"="\n"; print "@arr";

    Regards,
    Gubendran

Re: match word on line - match word on another line - print lines
by Random_Walk (Prior) on Jan 12, 2005 at 13:56 UTC

    you could also try this

    cat YourFile|perl -pe'$/="Title:";chomp;$_=/invalid url/?"Title:".$_:" +"'

    A quick explanation as this does look a bit line noise like. Perl is started with the options p and e. e gives the code to execute on the command line, p puts a while loop around the code with a continue block that just prints $_.

    A very useful trick is to deparse a script to see better what is going on, lets do that now to make it more readable and so you can see the while and print added by the -p

    pre> perl -MO=Deparse -pe'$/="Title:";chomp;$_=/invalid url/?"Title:". +$_:""' -e syntax OK LINE: while (defined($_ = <ARGV>)) { $/ = 'Title:'; chomp $_; $_ = /invalid url/ ? 'Title:' . $_ : '' } continue { print $_; }
    $/ is the input record seperator and by setting this to "Title:" I get perl to read one whole block at a time (up to and including the next occurance of Title: or EOF).

    The chomp removes the record seperator (Title:) from the end of the record, trailing titles would be ugly.

    The last part sets $_ depending on whether the block we are examining contains the string "invalid url". The Test?value1:value2 construct returns the first value if the test is true and the second if it fails. In this case we either fix up $_ for printing by prefixing "Title:" or we set it to an empty string so nothing is printed.

    Cheers,
    R.

Re: match word on line - match word on another line - print lines
by perlsen (Chaplain) on Jan 12, 2005 at 11:50 UTC

    if u wish just try this in your file

    input "test.txt"

    *******************************

    Title: Mary moo-cow 856 invalid

    Title: the mechanics 857 valid

    Title: Mary moo-cow 858 invalid

    Title: the mechanics 856 valid

    Title: Mary moo-cow 859 invalid

    Title: the mechanics 8500 valid

    undef $/; open(FIN,"d:\\temp.txt"); $str=<FIN>; close($str); while($str =~m#Title: (.*?) invalid#gi) { push(@arr,$1); } print "$_\n" for @arr;

    output

    ***********

    Mary moo-cow 856

    Mary moo-cow 858

    Mary moo-cow 859