A couple of comments on what you have.
As you are reading line-by-line, you will only ever get one newline character which will be at the ned of the line. Therefore, the /gs options on s/\r|\n//gs; are redundant. The /g because there can be only one \n (\r is most unlikely to occur!). The \s because unless your regex contains one or .'s, /s does nothing. In any case, what I assume you are trying to do is remove the trailing newline, in which case, see chomp which is design for doing exactly this.
With your 3 if statements, all 3 conditions are being tested for every line you read. As only one of them can ever match a given line, you would be better coding that as an if(...){}elsif(...){}elsif(...){}else{} cascade.
That said, the problem with processing multi-line records line-wise, is that if forces you to retain state. Ie. You have to remember what the last thing you parsed was in order to know how to handle the next line.
#! perl -slw
use strict;
my( $hostname, @dnsservers, $nodetype );
my $last = '';
while (<DATA>) {
chomp;
if ( /Host Name.*?:\s*(.*)$/ ) {
$hostname = $1;
$last = 'host';
}
elsif ( /DNS Servers.*?:\s*(.*)$/ ) {
@dnsservers = $1;
$last = 'dns';
}
elsif ( /Node Type.*?:\s*(.*)$/ ) {
$nodetype = $1;
$last = 'node';
}
elsif( !/:/ and $last eq 'dns' ) {
print '?';
push @dnsservers, $1 if /\s+(\S+)$/;
}
else{
warn "Unknown linetype at $. : '$_'\n";
}
}
print $hostname, $/, join' | ', @dnsservers, $/, $nodetype;
__DATA__
Host Name . . . . . . . . . : LAPTOP.no.cox.net
DNS Servers . . . . . . . . : 205.152.132.211
181.171.2.11
10.10.10.1
Node Type . . . . . . . . . : Broadcast
Whilst that does the job, I'm not fond of flag variables and try and avoid them where I can. In this case, perl can remember the state for you -- which is almost as bad in some ways, but it's there, so you might as well make use of it.
As the output from ipconfig is unlikely to be much more that a hundred or so bytes, there is no reason not to read the whole thing into scalar, and then use the regex engines "memory" (/gc options) of where it has got to in processing the string, to allow you to nibble away at it a piece at a time.
#! perl -slw
use strict;
my $ipConfig = do{ local $/; <DATA> };
my $hostName = $1
if $ipConfig =~ m[Host Name . . . . . . . . . : (\S+)\s*\n]gc;
my @dnsIPs = $ipConfig =~ m[(?:\s*([0-9.]+)\n)]gc
if $ipConfig =~ m[DNS Servers . . . . . . . . :]gc;
my $nodeType = $1
if $ipConfig =~ m[Node Type . . . . . . . . . : (\S+)\s*\n];
print $hostName, $/, join( ' | ', @dnsIPs), $/, $nodeType;
__DATA__
Host Name . . . . . . . . . : LAPTOP.no.cox.net
DNS Servers . . . . . . . . : 205.152.132.211
181.171.2.11
10.10.10.1
Node Type . . . . . . . . . : Broadcast
Note: That can just as easily be structured using 'normal' if statements
#! perl -slw
use strict;
my $ipConfig = do{ local $/; <DATA> };
my( $hostName, @dnsIPs, $nodeType );
if( $ipConfig =~ m[Host Name . . . . . . . . . : (\S+)\s*\n]gc ) {
$hostName = $1;
}
if( $ipConfig =~ m[DNS Servers . . . . . . . . :]gc ) {
@dnsIPs = $ipConfig =~ m[(?:\s*([0-9.]+)\n)]gc;
}
if( $ipConfig =~ m[Node Type . . . . . . . . . : (\S+)\s*\n] ) {
$nodeType = $1;
}
print $hostName, $/, join( ' | ', @dnsIPs), $/, $nodeType;
__DATA__
Host Name . . . . . . . . . : LAPTOP.no.cox.net
DNS Servers . . . . . . . . : 205.152.132.211
181.171.2.11
10.10.10.1
Node Type . . . . . . . . . : Broadcast
Except now I have to pre-declare the results variables and, to my eyes, the purpose of the code has become obscured by the structure. In the previous version is was very obvious that the three blocks of code produced 3 sets of results and what they were called. In this version, I have to look much more closely to see what is going on...but that's me:)
Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
Hooray!
Wanted!
|