Satish
Satish

Reputation: 15

Extracting data between keywords into an array using perl

I have file which has keywords like Frame 1, Frame 2 , Frame 3 ... Frame 100+, I want to extract data between each frames and place it in array. I tried , but i am not getting as per my need. I keep getting matched line. tried two ways.

my $key1 = "Frame 1" ;
my $key2 = "Frame 2";

while (<ReadHandle>){
    if (/^$key1/../^$key2/){
        @linearray=$_;
        print "\n  @linearray \n" ;
    }
}

this will print all lines. and second try as follows

my $key1 = "Frame" ;

while (<ReadHandle>){
    if (/^$key1/){
        @linearray=$_;
        print "\n  @linearray \n" ;
    }
}   

this will print only matched lines not data between.

my file looks like below

Frame 1: 140 bytes on wire (1120 bits), 140 bytes captured (1120 bits)
    Encapsulation type: Ethernet (1)
    Arrival Time: Jun 11, 2014 16:03:37.864278820 India Standard Time
Ethernet II, Src: Cisco_a9:94:0a (00:30:96:a9:94:0a), Dst: IPv6mcast_00:00:00:0d (33:33:00:00:00:0d)
Frame 2: 90 bytes on wire (720 bits), 90 bytes captured (720 bits)
    Encapsulation type: Ethernet (1)
Internet Protocol Version 6, Src: ::200:1:1:2 (::200:1:1:2), Dst: ff02::1:ff01:1 (ff02::1:ff01:1)
    0110 .... = Version: 6

so on.. any help or suggestion is much appreciated.

Upvotes: 1

Views: 122

Answers (2)

jaypal singh
jaypal singh

Reputation: 77155

If you file is not very big then you can read the entire file in to a string and split them on Frame. This way you will have one array element for entire Frame.

use strict;
use warnings; 
use Data::Dumper; 

my $data = do{ undef $/; <DATA> };
my @linearray = split /(?m)(?=^Frame \d+:)/, $data; 

print Dumper \@linearray;

__DATA__
Frame 1: 140 bytes on wire (1120 bits), 140 bytes captured (1120 bits)
    Encapsulation type: Ethernet (1)
    Arrival Time: Jun 11, 2014 16:03:37.864278820 India Standard Time
Ethernet II, Src: Cisco_a9:94:0a (00:30:96:a9:94:0a), Dst: IPv6mcast_00:00:00:0d (33:33:00:00:00:0d)
Frame 2: 90 bytes on wire (720 bits), 90 bytes captured (720 bits)
    Encapsulation type: Ethernet (1)
Internet Protocol Version 6, Src: ::200:1:1:2 (::200:1:1:2), Dst: ff02::1:ff01:1 (ff02::1:ff01:1)
    0110 .... = Version: 6

Output:

$VAR1 = [
          'Frame 1: 140 bytes on wire (1120 bits), 140 bytes captured (1120 bits)
    Encapsulation type: Ethernet (1)
    Arrival Time: Jun 11, 2014 16:03:37.864278820 India Standard Time
Ethernet II, Src: Cisco_a9:94:0a (00:30:96:a9:94:0a), Dst: IPv6mcast_00:00:00:0d (33:33:00:00:00:0d)
',
          'Frame 2: 90 bytes on wire (720 bits), 90 bytes captured (720 bits)
    Encapsulation type: Ethernet (1)
Internet Protocol Version 6, Src: ::200:1:1:2 (::200:1:1:2), Dst: ff02::1:ff01:1 (ff02::1:ff01:1)
    0110 .... = Version: 6
'
        ];

Upvotes: 1

mpapec
mpapec

Reputation: 50657

You can use array of array,

my @linearray;
while (<ReadHandle>){
   push @linearray, [] if /^Frame/;
   push @{ $linearray[-1] }, $_ if @linearray;
}   

use Data::Dumper;
print Dumper \@linearray;

Upvotes: 3

Related Questions