Perl Command Line Arguments Used In Regular Expressions
Question: Given various strings in a text file that are in this format:

    
    
    199.72.81.55 - - [01/Jul/1995:00:00:01 -0400] "GET /history/apollo/ HTTP/1.0" 200 6245
    

I am trying to read in a number from the command line like this:

    
    
    type small_access_log_Jul95_01.txt | perl FLTR_WLOG_STATUS_CODES.pl 200
    

The "small_access_log" txt file contains a line of the format before given on
each line. I am having trouble reading in and using the argument "200" in a
search, because it assigns 200 to be the first argument, it seems. Here is the
code that I'm working on:

    
    
    use strict;
    use warnings;
    
    
    while ( <> ) {
    
     if ($_ =~ /"[$ARGV[1]]"/){
     print $_;}
    
     }
    

It is only supposed to print the lines that contain that "200" or whatever is
input through the command line.

Here is the working version in python:

    
    
    import sys
    import re
    
    TEXT = sys.argv[1]
    for n in [x for x in sys.stdin.readlines() if re.search(".*?"+re.escape(TEXT) +"\s([0-9]+)$",x)]:
        print n
    

So what do I need to do differently with the command line in perl to make this
work?


Answer: The first parameter to a Perl program is in `$ARGV[0]`, and the empty diamond
operator reads data from the files named in `@ARGV`

You need to write your program like this. It removes the pattern parameter
from the end of `@ARGV` before using it in the loop, and takes advantage of
Perl's `$_` variable being the default parameter to many operators

The `\Q` in the regex forces all following non-alphanumeric characters to be
escaped, and hence taken literally. That includes the square brackets and the
_contents_ of `$pattern`, which may otherwise be taken as regex metacharacters
with a special meaning

    
    
    use strict;
    use warnings;
    
    my $pattern = pop @ARGV;
    
    while ( <> ) {
        print if /\Q[$pattern]/;
    }
    

and you should run it like this

    
    
    perl FLTR_WLOG_STATUS_CODES.pl small_access_log_Jul95_01.txt 200
    

### Update

If you're forced to accept the data input from STDIN instead of from a
command-line file name, then you need to do this

    
    
    use strict;
    use warnings;
    
    my $pattern = pop @ARGV;
    
    while ( <STDIN> ) {
        print if /\Q[$pattern]/;
    }
    

and you should run it like this

    
    
    type small_access_log_Jul95_01.txt | perl FLTR_WLOG_STATUS_CODES.pl 200
    

