# Structured instructions for simple extraction script

I have a rather simple task in trying to extract keywords from input.dat which looks like:

func1
{
yes         true;
keyword123  (1.1 0 -0.3);
gamma       (0 1 0);
dir         (1 0 0);
func2
{
yes         false;
keyword123  (1.1 0 -0.3);
gamma       (0 0 1);
dir         (1 0 0);


In this case I want to get the first entry in the vector of keyword123. If the lines containing the keyword aren't identically, the script should stop with an error. I feel that this should be a one- or twoliner in PERL using RegEx but it took me some time to get the following script:

#!/usr/bin/perl -w

use strict;

my $path = "./input.dat"; # array @grepped of lines containing keyword my @grepped=(); open(FILE,"$path") or die "error on opening $path:$!\n";
while (my $line = <FILE>) { if ($line=~ /keyword123/i){push(@grepped,"$line")}; } close(FILE); # get array @unique of unique lines my %seen; my @unique = grep {!$seen{$_}++} @grepped; # continue with$unique if keyword-line is unique
my $unique; if (scalar @unique eq 1) {$unique=$unique[0]; } else { die "entry not unique, exiting:$!\n";
}

# get string between brackets
$unique =~ /$$(.+?)$$/; my$final = $1; # cut after first space$final =~ s/\s.*//s;
print "keyword123: $final\n";  The script is giving the correct output but this can't be the best work, so any help/hint would be highly appreciated. ## 2 Answers This is how I would implement it: #!/usr/bin/perl use warnings; use strict; my$file = 'input.dat';
open my $IN, '<',$file or die $!; my$uniq;
while (my $line = <$IN>) {
next unless $line =~ /^\s*keyword123/; if (defined$uniq and $line ne$uniq) {
die "Entry not unique. Exiting.\n";
}
$uniq =$line;
}
$uniq =~ s/.*$$(.*)$$.*/$1/;
$uniq =~ s/\s.*//; print "keyword123:$uniq";


You can check the uniqueness each time you read the keyword line in. Once you find a non-unique line, you can stop right at the moment, no need to search the rest of the file.

I beat it down to this (below). Since you didn't do anything with the other information you accumulated, I chose the early-out strategy.

my $k123; open( my$fh, '<', './input.dat' ) or die "error on opening $path:$!\n";
while ( my $l = <$fh> ) {
chomp $l; next unless$l =~ m/keyword123/i;
$k123 //=$l;
die "Entry not unique!" unless $k123 eq$l;
}
close $fh; say "keyword123: ", ($k123 =~ /$$([^)]+)$$/ );