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

Wow, you guys are great! My Perl script is now only 10 lines, and works as I wanted it to. I'll need to add some error handling later, it outputs a -1 if the number has already been converted. A small thing that won't mess up my plans. (With regards to "simple padding of IP addresses")

My next script is importing an array, 4 deep, unspecified legnth. After doing this, I need to compare a different list to my hash table, and see if my number is between $ip and the second cell which is $ip2. I'm doing something wrong though. It's not working.

Thanks,
Carrie

#!/perl # open INFO, '<IPs.txt' or die; # Open the f +ile @line1 = <INFO> ; # Read it in +to an array close INFO; # Close the f +ile my %table; # Create a table open IN, '<source.txt' or die; # Name the file + with source addresses while (<IN>) { # Read file into table chomp; my($ip, $ip2, $country, $region) = split(' ',/,/,4); # Spli +t the IP address from the Country $table{$ip} = $region; } close IN; open(OUT, '>>conversion.txt') or die; foreach $line1 (@line1) # assign @l +ine1 to $line1, one at a time { if ($line1 >= $table{$ip} & $line1 <= $table{$ip2} ) { + # Compare the entry from log group to table print OUT $line1, ' ',$table{$line1},"\n" ; # Prints th +e line of the table } else {print OUT $line1;} } close OUT;

Edited 2002-07-25 by Ovid

Replies are listed 'Best First'.
Re: comparing list to 2 cells in array
by DamnDirtyApe (Curate) on Jul 25, 2002 at 23:55 UTC

    As best as I can understand, you are trying to do the following: check a list of IP addresses (IPs.txt) against a list of IP address ranges (provided in source.txt), and print each address in the list of IP addresses, along with a region if the address matched a range.

    Going on this premise, I've rewritten most of your code to do just that. The big problems with your existing code are as follows:

    • No use strict or use warnings -- always, always, always write your code with these two pragmas.
    • Strange split syntax -- I don't know what you intended to do with split(' ',/,/,4), but that ain't it.
    • Non-existent hash keys -- You try to do a comparison against $table{$ip2}, which you've never assigned to.
    • Incorrect comparisons -- the <= and >= operators are for numerical comparisons. The IP addresses in your program are strings.
    • Non-descriptive variable names -- variable names like $line1 get confusing because they have no meaning when trying to understand an expression.

    Here is the code, rewritten to comply with the guidelines I listed, and intended to accomplish the goal I guessed you're trying for.

    source.txt
    123.123.123.123 124.124.124.124 Canada BC 111.111.111.111 112.112.112.112 Canada AB 11.11.11.11 12.12.12.12 USA WA 22.22.22.22 23.23.23.23 USA OR 33.33.33.33 34.34.34.34 USA CA
    IPs.txt
    10.10.10.10 11.11.12.12 123.123.122.122 123.123.124.125
    Perl program
    #!perl # use strict ; use warnings ; open INFO, 'IPs.txt' or die $! ; chomp( my @IPs = <INFO> ) ; close INFO ; my @rows = () ; open IN, ' source.txt' or die $! ; while (<IN>) { next if /^$/ ; my %table = () ; @table{ 'ip', 'ip2', 'country', 'region' } = split ; $table{ 'num_ip' } = sprintf '%03d' x 4, split /\./, $table{ 'ip' + } ; $table{ 'num_ip2' } = sprintf '%03d' x 4, split /\./, $table{ 'ip2 +' } ; push @rows, \%table ; } close IN; open OUT, '>>conversion.txt' or die $! ; foreach my $ip ( @IPs ) { my $match = 0 ; my $num_ip = sprintf '%03d' x 4, split /\./, $ip ; foreach my $row ( @rows ) { if ( $num_ip >= $row->{'num_ip'} && $num_ip <= $row->{'num_ip2 +'} ) { printf OUT "%-16s %s\n", $ip, $row->{'region'} ; $match++ ; } } printf OUT "%-16s\n", $ip if !$match ; } close OUT;
    Output
    10.10.10.10 11.11.12.12 WA 123.123.122.122 123.123.124.125 BC

    Let me know how close to the mark this is.


    _______________
    D a m n D i r t y A p e
    Home Node | Email
      This seems like it would work very well. I have ran it, and I'm getting an error "%table requires a specific package name". I looked this up, and so I know that it is because I'm using "Use Strict" and I need to declare something. I saw someone about declaring vars, defs, and something else, but didn't understand it. So can I just declare %table to get it to work? I looked at it, and normally my %table should work, because it is local, but, the code didn't like it anyway. Thanks, Carrie

        What OS/Perl version are you running? This works fine for me on RH7.3, with Perl 5.6.1.


        _______________
        D a m n D i r t y A p e
        Home Node | Email

        Actually, you declared a hash %table and used an array @table.

        Update: my fault. I just learned that you can write things like @table{ 'ip', 'ip2', 'country', 'region' } = split ;

Re: comparing list to 2 cells in array
by thelenm (Vicar) on Jul 25, 2002 at 22:10 UTC
    I don't mean to be rude, but it's very hard to read your post(s) when they're not formatted nicely. Please read Writeup Formatting Tips, which explains how to format Perl code so that everyone can read it easily. Basically, just surround your code with <CODE> ... </CODE> tags. You can tell if your post looks good or not by taking a look at it after hitting the "preview" button. Using <CODE> tags will help us help you!

    Update: A nice volunteer has added formatting, so this node isn't as relevant anymore. Still, you should be aware that when there are no <CODE> tags around Perl code, it takes someone else's time to fix it.

    -- Mike

    --
    just,my${.02}

Re: comparing list to 2 cells in array
by FamousLongAgo (Friar) on Jul 25, 2002 at 22:35 UTC
    One tip on style, and one tip on substance:

    - In general, your comments should express things that aren't obvious from your code. Reiterating what the code is doing actually makes the program less readable, especially when you append the comments to each line. Try commenting at a higher level of abstraction

    - You are using the bitwise operator '&' where you almost certainly want the logical comparison operator '&&' in your last if statement.
Re: comparing list to 2 cells in array
by DamnDirtyApe (Curate) on Jul 25, 2002 at 22:52 UTC

    A little more information would help me understand this much better.

    • Do you have some sample data from each file you could post?
    • What is it you are trying to accomplish here? Not in terms of your code, but what is this script's purpose?

    _______________
    D a m n D i r t y A p e
    Home Node | Email