Avatar of ashsysad
ashsysad
Flag for United States of America asked on

Script help

Hello,

I have a text-pattern as shown below:
-----------------------------------------------------------------------------------------------------------------------------------
Pinging ora-stage-inf-d1.itc.com [172.113.52.123] with 32 bytes of data:
Reply from 172.113.52.123: bytes=32 time=213ms TTL=54

Pinging ora-stage-fmsoa-a4.itc.com [172.113.68.139] with 32 bytes of data:
Request timed out.

Pinging ora-stage-fmsoa-d1.itc.com [172.113.68.198] with 32 bytes of data:
Request timed out.
-----------------------------------------------------------------------------------------------------------------------------------------

I have developed a perl script that captures the Hostname and IP Address, and displays it in tabular form as shown below:


# cat ping_res.pl
#!/usr/bin/perl

@inputfile = `cat pingresult.txt`;
$status;

print "Hostname\t\t\t\tIP Address\t\tPing Status\n";
foreach(@inputfile)
{
        if($_ =~ m/Pinging\s(\S+)\s\[(\S+)\]\swith/) {
                $hstnm = $1;
                $ipaddr = $2;
                print "$hstnm\t\t$ipaddr\n";
        }
}



Hostname                                 IP Address                 Ping Status
ora-stage-inf-d1.itc.com                172.113.52.123
ora-stage-fmsoa-a4.itc.com           172.113.68.139
ora-stage-fmsoa-d1.itc.com           172.113.68.198

My requirement is, I want to capture the Ping Status from the text-pattern. i.e., if the next line (after Pinging host......................) has the string "Reply from", a variable called "$status" should be set with the string "Success".

The other case, if the next line(after Pinging host............) has the string "Request timed out", the $status variable should be set with the string "Timed out".

Please help me to complete this. Thanks.

The expected output is shown here:
Hostname                                 IP Address                 Ping Status
ora-stage-inf-d1.itc.com                172.113.52.123         Success
ora-stage-fmsoa-a4.itc.com           172.113.68.139         Timed out
ora-stage-fmsoa-d1.itc.com           172.113.68.198         Timed out
PerlRegular ExpressionsShell Scripting

Avatar of undefined
Last Comment
ashsysad

8/22/2022 - Mon
ASKER CERTIFIED SOLUTION
Lee Wadwell

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
FishMonger

If this is a one time script, then parsing your pingresult.txt file is fine, but if you need to do this on a regular basis, I'd suggest taking a step back and rework your approach.

Instead of redirecting the output of the Windows ping command to a file and parsing it, I'd do the ping inside the Perl script with the aide of the Net::Ping module.

Link to Net::Ping documentation.
ashsysad

ASKER
@FishMonger, Thanks for your suggestion.
ashsysad

ASKER
That was awesome !! Thanks a lot for your help !!
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
ashsysad

ASKER
@lwadwell,  I tried to add another string pattern to the text file by modifying your script but am getting duplicate output. It would be great if you correct my syntax.

Ping request could not find host ora-stage-fmsoa-a3.itc.com. Please check the name and try again.


open(INFILE, "pingresult.txt")  or die "Cannot seem to open the file ($!)";
printf("%-30s %-15s %-50s\n", "Hostname", "IP Address", "Ping Status");
while ($l = <INFILE>) {
  if($l =~ m/Pinging\s(\S+)\s\[(\S+)\]\swith/) {
    $hstnm = $1;
    $ipaddr = $2;
    $status = "unknown";
    $r = <INFILE>;
    $status = "Success"                 if $r =~ /^Reply from/;
    $status = "Request timed out"       if $r =~ /^Request timed out./;
    printf("%-30s %-15s %-50s\n", $hstnm, $ipaddr, $status);
    }
  }
close("INFILE");
open ("INFILE2", "pingresult.txt")  or die "Cannot seem to open the file ($!)";
while (<INFILE2>) {
    if($_ =~ m/^Ping\srequest\scould\snot\sfind\shost\s(\S+)/) {
        $hstnm = $1;
        $ipaddr = 'Unknown';
        $status = 'Not-reachable';
        printf("%-30s %-15s %-50s\n", $hstnm, $ipaddr, $status);
        }
}

Hostname                            IP Address             Ping Status
ora-stage-inf-d1.itc.com       172.113.52.123     Success
ora-stage-fmsoa-a4.itc.com     172.113.68.139  Request timed out
ora-stage-fmsoa-d1.itc.com     172.113.68.198  Request timed out
ora-stage-osb-v1.itc.com       172.113.68.214     Success
ora-stage-fmsoa-a3.itc.com.    Unknown             Not-reachable
ora-stage-fmsoa-a3.itc.com.    Unknown         Not-reachable
Lee Wadwell

You do not need to open and loop through the file a second time ... your new logic can be added to the existing while loop.  Unless you wanted the output in a particular order - and even then, I would use and array or hash to save the results before looping the same file twice.

open(INFILE, "pingresult.txt")  or die "Cannot seem to open the file ($!)";
printf("%-30s %-15s %-50s\n", "Hostname", "IP Address", "Ping Status");
while ($l = <INFILE>) {
  if($l =~ m/Pinging\s(\S+)\s\[(\S+)\]\swith/) {
    $hstnm = $1;
    $ipaddr = $2;
    $status = "unknown";
    $r = <INFILE>;
    $status = "Success"                 if $r =~ /^Reply from/;
    $status = "Request timed out"       if $r =~ /^Request timed out./;
    printf("%-30s %-15s %-50s\n", $hstnm, $ipaddr, $status);
  }
  if($l =~ m/^Ping\srequest\scould\snot\sfind\shost\s(\S+)/) {
    $hstnm = $1;
    $ipaddr = 'Unknown';
    $status = 'Not-reachable';
    printf("%-30s %-15s %-50s\n", $hstnm, $ipaddr, $status);
  }
}
close(INFILE);

Open in new window


There is no obvious problem - I ran your code and I did not get duplicate output.  Please ensure you do not have duplicate in your input file.
ashsysad

ASKER
@lwadwell, Yes, i just found out there is a duplicate entry in the input file.

Appreciate your help. Thanks a lot again !!!
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.