Multiple Line Extraction

D

doni

Hi,

I was wondering how can I read two lines from a file at a time and
extract the data from the first line and second line onto different
variables.

Below is the data snippet that I am using to write my program. The
data contains the path information extracted from each node. The node
value which occurs at the beginning of the next line after "from" line
is the one whose path information we are extracting.

If the line does not contain "from" field at the beginning, I want to
read 2 lines and extract the contents of the first line and second
line onto different fields before we iterate through the while loop .
If the line contains "from" field read the line and iterate through
the while loop to read the next line from the file.

from to reachable rssi
08:c0 09:c3 yes 3
09:c3 08:c0 yes 2
08:c0 09:c4 yes 7
09:c4 08:c0 yes 7
08:c0 09:c8 yes 3
09:c8 08:c0 yes 3
08:c0 09:d8 no 8
09:d8 08:c0 no 7
from to reachable rssi
09:c3 08:22 yes 15
08:22 09:c3 yes 10
09:c3 08:c0 yes 2
08:c0 09:c3 yes 3
09:c3 09:c4 no 4
09:c4 09:c3 no 8
from to reachable rssi
09:c4 08:c0 yes 7
08:c0 09:c4 yes 7
09:c4 09:c3 no 8
09:c3 09:c4 no 4
09:c4 09:c8 yes 7
09:c8 09:c4 yes 7
from to reachable rssi
09:c8 08:c0 yes 3
08:c0 09:c8 yes 3
09:c8 09:c4 yes 7
09:c4 09:c8 yes 7
09:c8 09:d8 yes 6
09:d8 09:c8 yes 6
from to reachable rssi
09:d8 08:22 yes 4
08:22 09:d8 yes 7
09:d8 08:c0 no 7
08:c0 09:d8 no 8
09:d8 09:c8 yes 6
09:c8 09:d8 yes 6


Here is the code I wrote to perform the above operation.


#! /usr/bin/perl

use strict;
use warnings;

my $ex_data = 'routed_info';
open (NETSTAT,$ex_data) || die("Cannot Open File: $!");

my $route_node; my $rssi;
my @mac_id;
my $first_node; my $second_node;
my $first_rssi; my $second_rssi;
my $first_link; my $second_link;

while (<NETSTAT>) {
chomp;
my @words = split;
if (/^([a-z]+)\s+([a-z]+)\s+([a-z]+)\s+([a-z]+)/) {
$route_node = 1;
}
elsif ($route_node == 1) {
push (@mac_id, $words[0]);
$route_node = 0;
$first_node = $words[1]; $first_link = $words[2]; $first_rssi
= $words[3];
next <NETSTAT>;
$second_link = $words[2]; $second_rssi = $words[3];
if (($first_link eq "yes") && ($second_link eq "yes")) {
$rssi = ($first_rssi + $second_rssi)/2;
print "Combined RSSI value from $words[1] and
$first_node is: $rssi\n";
}

}
else {
}
}
close(NETSTAT) || die("Cannot close $ex_data: $!");


Pls, let me know If I I havent clearly described my issue here. Can
anyone let me know how can I perform this.

Thanks,
doni
 
J

John W. Krahn

doni said:
I was wondering how can I read two lines from a file at a time and
extract the data from the first line and second line onto different
variables.

Below is the data snippet that I am using to write my program. The
data contains the path information extracted from each node. The node
value which occurs at the beginning of the next line after "from" line
is the one whose path information we are extracting.

If the line does not contain "from" field at the beginning, I want to
read 2 lines and extract the contents of the first line and second
line onto different fields before we iterate through the while loop .
If the line contains "from" field read the line and iterate through
the while loop to read the next line from the file.

from to reachable rssi
08:c0 09:c3 yes 3
09:c3 08:c0 yes 2

[ SNIP ]

09:d8 09:c8 yes 6
09:c8 09:d8 yes 6


Here is the code I wrote to perform the above operation.


#! /usr/bin/perl

use strict;
use warnings;

my $ex_data = 'routed_info';
open (NETSTAT,$ex_data) || die("Cannot Open File: $!");

my $route_node; my $rssi;
my @mac_id;
my $first_node; my $second_node;
my $first_rssi; my $second_rssi;
my $first_link; my $second_link;

while (<NETSTAT>) {
chomp;
my @words = split;
if (/^([a-z]+)\s+([a-z]+)\s+([a-z]+)\s+([a-z]+)/) {
$route_node = 1;
}
elsif ($route_node == 1) {
push (@mac_id, $words[0]);
$route_node = 0;
$first_node = $words[1]; $first_link = $words[2]; $first_rssi
= $words[3];
next <NETSTAT>;
$second_link = $words[2]; $second_rssi = $words[3];
if (($first_link eq "yes") && ($second_link eq "yes")) {
$rssi = ($first_rssi + $second_rssi)/2;
print "Combined RSSI value from $words[1] and
$first_node is: $rssi\n";
}

}
else {
}
}
close(NETSTAT) || die("Cannot close $ex_data: $!");


Pls, let me know If I I havent clearly described my issue here. Can
anyone let me know how can I perform this.

It looks like this is close to what you want:

#!/usr/bin/perl
use warnings;
use strict;

my $ex_data = 'routed_info';
open NETSTAT, '<', $ex_data or die "Cannot Open '$ex_data' $!";

my $flag;
my %data;
while ( <NETSTAT> ) {
next unless /^ ([[:xdigit:]]{2}:[[:xdigit:]]{2})
\s+
([[:xdigit:]]{2}:[[:xdigit:]]{2})
\s+
(yes|no)
\s+
(\d+)
/x;

my $key = join ' and ', ++$flag & 1 ? ( $1, $2 ) : ( $2, $1 );

$data{ $key }{ reachable } .= $3;
$data{ $key }{ rssi } += $4;

next unless $data{ $key }{ reachable } eq 'yesyes';

print "Combined RSSI value from $key is: ", $data{ $key }{ rssi } / 2, "\n";

%data = ();
}

__END__



John
 
D

doni

while ( <NETSTAT> ) {
next unless /^ ([[:xdigit:]]{2}:[[:xdigit:]]{2})
\s+
([[:xdigit:]]{2}:[[:xdigit:]]{2})
\s+
(yes|no)
\s+
(\d+)
/x;

I was wondering how does this matching operation works especially
[[:xdigit:]]{2} in this above statement.

Also, can you explain me how this below statement works as I couldnt
understand how you extract the data from the 2 lines.
my $key = join ' and ', ++$flag & 1 ? ( $1, $2 ) : ( $2, $1 );

$data{ $key }{ reachable } .= $3;
$data{ $key }{ rssi } += $4;

next unless $data{ $key }{ reachable } eq 'yesyes';

print "Combined RSSI value from $key is: ", $data{ $key }{ rssi } / 2, "\n";

Thanks,
doni
 
D

DJ Stunks

I was wondering how can I read two lines from a file at a time and
extract the data from the first line and second line onto different
variables.
Below is the data snippet that I am using to write my program. The
data contains the path information extracted from each node. The node
value which occurs at the beginning of the next line after "from" line
is the one whose path information we are extracting.
If the line does not contain "from" field at the beginning, I want to
read 2 lines and extract the contents of the first line and second
line onto different fields before we iterate through the while loop .
If the line contains "from" field read the line and iterate through
the while loop to read the next line from the file.

(snipped)

You might find the natatime function from List::MoreUtils useful:

use List::MoreUtils qw/natatime/;

use constant {
FROM => 0,
TO => 1,
REACHABLE => 2,
RSSI => 3,

};

my @netstat = grep !/^from/, <DATA>;
my $iterator = natatime 2, @netstat;

while (my @pair = map { [ split ] } $iterator->())
{
if ($pair[0][REACHABLE] eq 'yes' and $pair[1][REACHABLE] eq 'yes')
{
print "$pair[0][FROM] $pair[0][TO] = ",
($pair[0][RSSI] + $pair[1][RSSI])/2,
"\n";
}

}

__DATA__
from to reachable rssi
08:c0 09:c3 yes 3
09:c3 08:c0 yes 2
08:c0 09:c4 yes 7
09:c4 08:c0 yes 7
08:c0 09:c8 yes 3
09:c8 08:c0 yes 3
08:c0 09:d8 no 8
09:d8 08:c0 no 7

nice script, Steven. :)

I might quibble with your K&R-style indentation, but I suppose I
won't :)~

-jp
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,738
Latest member
JinaMacvit

Latest Threads

Top