Deepesh Tripathi
Deepesh Tripathi

Reputation: 13

Regular Expression pattern storing in array

I am new to perl and want to read a file in which IP are stored , i want to grep these IP and store in array , i am able to write the regex for this but out of three ips it always stores last ip of file in array , please help someone my code and file is like below.

my input file have follwing contents

Hi praveen how are10.23.54.86

10.87.98.65

10.98.76.54

my script o/p is

/pearl$ ./par.pl sdp.txt

10.98.76.54

and code is

#!/usr/bin/perl

open (INPUT,$ARGV[0]) || die "Can not open file:$!";

$i=0;

while(<INPUT>)
{
  $line=$_;
  ($arr,$arr1,$arr2)=($line=~m/\d+[\.]\d+[\.]\d+[\.]\d+/g);
}


close(INPUT);

print $arr,"\n";

I tried with array and as well as variable but same results its only stores last value.

Upvotes: 1

Views: 293

Answers (3)

Kenosis
Kenosis

Reputation: 6204

Consider using the Perl Module Regexp::Common to match the IPs, as it's been well-developed for this purpose:

use strict;
use warnings;
use Regexp::Common qw/net/;

my @IPs;

while (<>) {
    my ($IP) = /($RE{net}{IPv4})/;
    push @IPs, $IP if $IP;
}

print "$_\n" for @IPs;

Output from your data set:

10.23.54.86
10.87.98.65
10.98.76.54

A valid IP on a line is captured and placed into $IP. The next line pushes an IP onto @IPs if $IP contains one. Finally, the elements of @IPs are printed, if any.

Hope this helps!

Upvotes: 1

Benj
Benj

Reputation: 32428

You appear to have two problems:

  1. You appear to be filling 3 variables, not 4 (Unless you don't want the last number?)

  2. Your regex doesn't specify any capture groups so you're not saving out any values from the matched string.

You want something like:

while(<INPUT>)
{
  if( ($arr,$arr1,$arr2,$arr3) = /(\d+)\.(\d+)\.(\d+)\.(\d+)/g )
  {
    print "$arr $arr1 $arr2 $arr3\n";
  }
}

Or if you want to treat the matched numbers as a list try this:

while(<>)
{
  chomp;
  if( @array = /(\d+)\.(\d+)\.(\d+)\.(\d+)/g )
  {
    print @array;
  }
}

Upvotes: 0

sidyll
sidyll

Reputation: 59327

As you're reading one line at a time, and each line has only one address, of course you have only one output since the output is printed after the loop, not inside it on each iteration.

  • Use <>
  • Avoid unecessary variables (like $i)
  • Enable warnings
  • You most likely want to use an array to store your IPs

In the following code, your IPs will be stored in @ips.

#!/usr/bin/perl

use warnings;
use strict;

my @ips;

while (<>) {
    # not the optimal regex for IPs, I just simplifyied yours
    push @ips, m/(?:\d+\.){3}\d+/g;
}

print "@ips\n";
# --- or ---
print "$_\n" foreach @ips;

Upvotes: 2

Related Questions