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

my config file look like this :
eth0 Link encap:Ethernet HWaddr 00:0C:29:0F:9B:82 inet addr:192.168.8.76 Bcast:192.168.8.255 Mask:255.255.25 +5.0 inet6 addr: fe80::20c:29ff:fe0f:9b82/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:280252 errors:0 dropped:0 overruns:0 frame:0 TX packets:106184 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:35501675 (33.8 MiB) TX bytes:11696548 (11.1 MiB) Base address:0x1080 Memory:f4820000-f4840000 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:4664 errors:0 dropped:0 overruns:0 frame:0 TX packets:4664 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:7952486 (7.5 MiB) TX bytes:7952486 (7.5 MiB)
my script file look like this
open FILE,"config.txt" or die "cannot open file : $!"; $i = 1; while(<FILE>) { chomp ($_); # print "===$_"."\n"; @arr=split /\s+/, $_; #print "line is =>$arr[]". "\n\n"; print "Line $i ->$arr[0] $arr[1]"."\n"; foreach $line (@arr) { #print "My Elements -> $line\n"; if ($line =~ (/^addr:(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3} +)/)){ $ipaddr ="$1.$2.$3.$4\n"; print "$ipaddr"; } } $i++; # print $_; }
and when I run output look like this
Line 1 ->eth0 Link Line 2 -> inet 192.168.8.76 Line 3 -> inet6 Line 4 -> UP Line 5 -> RX Line 6 -> TX Line 7 -> collisions:0 Line 8 -> RX Line 9 -> Base Line 10 -> Line 11 ->lo Link Line 12 -> inet 127.0.0.1 Line 13 -> inet6 Line 14 -> UP Line 15 -> RX Line 16 -> TX Line 17 -> collisions:0 Line 18 -> RX
my expected output should be like this
eth0 => 192.168.8.76 lo => 127.0.0.1
I am not getting the expected output

Replies are listed 'Best First'.
Re: need to remove the extra line in regular expression
by greengaroo (Hermit) on Aug 22, 2012 at 13:16 UTC

    Now, it would also be good to have your "config.txt" file, but I'm going to try to answer your question anyway.

    You have two print statements in your code, the second is conditional, if it contains an IP address you parse it and print it, but the first print is not conditional, you print $arr[0] on every iteration of the loop. If you want to print it only when you find an IP address, put this in the if statement too.

    Take my advice. I don't use it anyway.
      I have added the config file please refer that
        You forgot the code tags again
        I have added the code, please refer that
Re: need to remove the extra line in regular expression
by aitap (Curate) on Aug 22, 2012 at 14:13 UTC

    By the way, use IO::Interface::Simple. It's more reliable than screenscraping ifconfig output.

    Also, use warnings and strict. This will help you to prevent many stupid errors which can otherwise occur easily.

    Edit: removed somewhat offensive part of the message caused by misunderstanding
    Sorry if my advice was wrong.
      Thanks for the suggestion. but can I get the expected out put without using IO module because I am extracting the output from config file. currentlty this is important for me.please suggest.
        Try something like this:
        my $interface; # declare the variable while (<>) { # if there are non-space symbols on the start of the line, # consider it interface name $interface = $1 if /^([\S]+)/; # $1 means first matched () group of s +ymbols # a group of numeric symbols or dots after "inet addr:" # is considered an IP-address print "$interface => $1\n" if /inet addr:([0-9.]+)/; # use /inet6? addr: ?([0-9a-f.]+)/ if you want to match IPv6-addresse +s }
        Sorry if my advice was wrong.
Re: need to remove the extra line in regular expression
by greengaroo (Hermit) on Aug 22, 2012 at 13:04 UTC
Re: need to remove the extra line in regular expression
by greengaroo (Hermit) on Aug 22, 2012 at 14:45 UTC

    This is what I would do:

    my @devices; open (FILE,"config.txt") or die "cannot open file : $!"; # Always put a label on your loop when using next CONFIG_LOOP: while ( my $line = <FILE> ) { # Never use $_ directly if ( $line =~ /^(\w+)\s+/ ) { # Adding to the array push( @devices, "$1 => " ); } elsif ( $line =~ (/inet\saddr:(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1 +,3})/) ) { # Adding the IP address to the last known device $devices[-1] .= "$1.$2.$3.$4\n"; } else { # Skipping other lines next CONFIG_LOOP; } } close (FILE); foreach my $device ( @devices ) { print $device; }
    Take my advice. I don't use it anyway.
      when I run the script I got the out put: eth0 => lo => But my expected output is eth0 => 192.168.8.76 lo => 127.0.0.1 and also please comment the line of code so that I can explain the co +de to my boss.