vkk05
vkk05

Reputation: 3222

Perl read data from file and extract certain line content

I am extracting certain data from file. Script should fetch Element value from given data based on active status. If the status is active I need to get corresponding Element value from previous line.

My code is below and its working perfeclty fine.

#!/usr/bin/perl

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

my @list;
my @lines = <DATA>;
foreach (0 .. $#lines) {
    chomp $lines[$_];
    next if (/^\s+$/);
    if ($lines[$_+1] =~ /active : yes/){
        if($lines[$_] =~ /Element=(\w+)/){
            push (@list, $1);
        }
    }
}
print Dumper(\@list);

__DATA__
Data : Element=123456
active : yes

Data : Element=789101
active : yes

Data : Element=23456
active : no

Expected dumper output is:

$VAR1 = [
          '123456',
          '789101'
        ];
  1. I need experts suggestion is this right way to fetch the data?
  2. The Empty lines which sepates each data contents not skiping using next if (/^\s+$/); statement.

Upvotes: 0

Views: 777

Answers (3)

Dave Cross
Dave Cross

Reputation: 69224

There's no right or wrong here, but this is what I'd do.

#!/usr/bin/perl

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

my @list;
$/ = '';

while (<DATA>) {
  chomp;
  next unless /active : yes/;
  if (/Element=(\d+)/) {
    push (@list, $1);
  }
}
print Dumper(\@list);

__DATA__
Data : Element=123456
active : yes

Data : Element=789101
active : yes

Data : Element=23456
active : no

The biggest difference is to use $/ = '' to put Perl into "paragraph mode", meaning that each time round the loop, you're dealing with an entire record (i.e. both lines together). This makes some of the logic somewhat easier.

Upvotes: 1

pmqs
pmqs

Reputation: 3705

Regarding the structure of the code, you can simplify it by matching both the Element line and the active line at the same time in a regular expression.

my @list;

# read all the input data into $data
local $/;
my $data = <DATA> ;

while  ($data =~ /Element=(\d+)\nactive : yes/g)
{
    push @list, $1
}

print Dumper(\@list);

Upvotes: 1

pmqs
pmqs

Reputation: 3705

The Empty lines which sepates each data contents not skiping using next if (/^\s+$/); statement.

The regular expression /^\s+$/ will only match blank lines that have at least one white space character.

You need /^\s*$/. That will match blank lines that have zero or more white space characters.

Upvotes: 0

Related Questions