m@cky has asked for the wisdom of the Perl Monks concerning the following question:

Hi Perl Experts, I've heard great things of what Perl can do and i'm trying to pick it up the hard way. However, i've got an urgent task to complete which i'm trying to write a simple Perl script to get the job done. I'm needed to read a log file and search/extract every line which contains a word (e.g. gateway) out to a seperate file. Below is what i've tried so far. Please don't mock me but show me some light on how to get this done. Your kind assistance will be greatly appreciated.
print "Specify file to read.\n"; $file = <STDIN>; chomp $file; print "Identified file is $file\n"; print "Is this correct?\n"; $confirm = <STDIN>; chomp $confirm; if ($confirm eq "yes") { print "Commencing work on $file.\n"; workings (); } else { #WHAT NEXT? } ## Subroutine to open & read logfile sub workings { open (LOGFILE, $file); #Open & read specified file while (<STDIN>) { #reads every line of file. if (/gateway/) { #HOW TO EXTRACT TO ANOTHER TXT FILE?

Replies are listed 'Best First'.
Re: search and extract lines which contain a word
by ikegami (Patriarch) on Mar 26, 2008 at 10:36 UTC
    On a unix system:
    grep 'gateway' infile > outfile
    On a unix system:
    perl -ne'print if /gateway/' infile > outfile
    On a Windows system:
    perl -ne"print if /gateway/" infile > outfile

    An example using file handles:

    # Usage: script.pl infile outfile # or # Usage: perl script.pl infile outfile use strict; use warnings; my ($qfn_in, $qfn_out) = @ARGV; open(my $fh_in, '<', $qfn_in) or die("Unable to read file \"$qfn_in\": $!\n"); open(my $fh_out, '>', $qfn_out) or die("Unable to create file \"$qfn_out\": $!\n"); while (<$fh_in>) { if (/gateway/) { print $fh_out $_; } }

    Update: Fixed copy & paste error mentioned in reply.
    Update: Must have been asleep! Fixed missing my mentioned in reply.

      Slight typo in the file handles code:
      open($fh_out, '<', $qfn_out)
      Should read::
      open($fh_out, '>', $qfn_out)

      Note, when using strict, both $fh_in and $fh_out must have "my" in front of them in the calls to open.

        I would argue that my should be there either way, but that Perl only detects the error when use strict; is missing.

        But that's debatable. Anyway, thanks. Fixed.

      Hi, perl -ne "print if /gateway/" infile > outfile This method works great! But how can search for multiple strings? E.g. I want to search for lines containing the string 'gateway' and 'TIMESTAMP' and extract the entire line if found. Please kindly advice, thank you!
        Hi Experts, Forget my last question post. I've managed to get it done. Not sure if i got it done 'intelligently' though. =P Can anyone please advice on this instead? Based on the current code below, how do i EXCLUDE extracting lines that contain any of the array of names defined, although strings 'gateway' & 'timestamp' are found in the particular line? E.g. ## To exclude extracting lines with username 'andrew' ## dcndksckdsnckdc gateway jdscjscjsdh timestamp andrew dkcd
        print "Specify full directory of logfile.\n"; $file = <STDIN>; chomp $file; print "\nIdentified file is $file\n"; print "Is this correct? (y/n)\n"; $confirm = <STDIN>; chomp $confirm; if ($confirm eq "y") { print "\nCommencing work on $file.\n"; workings(); } else { print "Terminating program...\n"; } ## Subroutine to open & read logfile sub workings { print"In Subroutine workings now.\n"; open (LOGFILE, $file); print "Opening logfile...\n"; open (OUT, ">>", 'D:\Temp\test.txt') or die "$!"; print "Opening output file...\n"; print "Checking for string GATEWAY...\n"; while (<LOGFILE>) { if (/gateway/) { $count = $count + 1; print OUT; print "Extracting line ...\n"; } elsif (/TIMESTAMP/) { $count = $count + 1; print OUT; print "Extracting line ...\n"; } } print "\nTotal of $count lines extracted.\n"; close OUT; close LOGFILE; } ##Array to contain usernames @names = qw(mddinzam khairulz sawaikha caoyx jchew khamshae hartinib t +eev xiaolh yettynm yussofyu leegm narayam karuppa doraira edanor raza +liha sambanr jwong lamks linwb rashid ongsp ooisc mohdrosn);
        perl -ne "print if /gateway/ && /TIMESTAMP/" infile > outfile
        you can have multiple alternatives:

        if /(gateway|TIMESTAMP)/

        A paren around the collection of alternatives, a | between each alternative.

Re: search and extract lines which contain a word
by Not_a_Number (Prior) on Mar 26, 2008 at 10:54 UTC

    In addition to ikegami's solutions above

    On a Windows system:

    findstr "gateway" infile > outfile