I am new to perl and am attempting to extract data from a file like I would with awk. I have gathered the data from the file and stored it in the array "array". I want to grab the only certain columns and only certain rows. For example, I want to only select the index of 7 (Q) and select the three numbers to eventually make a subroutine to average them out. I also want to be able to grab just a single field from say D for the date. There are very easy ways to do this with awk and cut, but I am having a very difficult time figuring out how to do this with Perl.
Here is the data.txt file
F gge0001x gge0001y gge0001z
D 12-30-2006 12-30-2006 12-30-2006
T 14:15:20 14:15:55 14:16:27
S a69 a69 a69
B 15.8 16.1 15
M gge06001 gge06001 gge06001
P 30.1 29.6 29.9
Q 20.2 22.3 23.4
I can get it to where I can select the index that I want, I just cant cut the fields
Performance Data
Q 20.2 22.4. 23.4
Here is my code so far...
use constant;
use strict;
use warnings;
use diagnostics;
my $my_file = 'data.txt';
my @array;
open my $fh, '<', 'data.txt'
or die "Cant open : ";
printf ("%10s", "Performance Data\n");
while(<$fh>)
{
if( /\bF|T|B|P|Q|R|H|O|C|K|W|L\b/)
{
push @array, $_;
}
}
my @tab = split(/\s+/, $array[2]);
print $tab[-2], [-3], "\n";
Thank you for you help
You can do it as oneliner, for example as:
perl -lanE 'print "@F[1,2,3]" if $F[0] eq "Q"' < data.txt
prints
20.2 22.3 23.4
for the meaning of the switches see prelrun.
Or using script - one pass:
use strict;
use warnings;
use feature 'say';
use Data::Dumper;
while(<>) {
chomp;
my @cols = split /\s+/;
if( $cols[0] eq 'Q' ) {
say "for Q: @cols[1,2,3]";
}
}
Use it as perl script.pl < data.txt (redirection). It prints
for Q: 20.2 22.3 23.4
If you want load the whole "matrix" beforehand
use strict;
use warnings;
use feature 'say';
#use Data::Dumper;
my $matrixref;
while(<>) {
chomp;
push @$matrixref, [split /\s+/];
}
#say Dumper $matrixref;
for my $lineref (@$matrixref) {
if( $lineref->[0] eq 'Q' ) {
say "for Q: @$lineref[1,2,3]";
}
}
again, using the perl script.pl < data.txt prints:
for Q: 20.2 22.3 23.4
Of course, you can change the while(<>) to while(<$fh>) and open the file internally... etc.
I think the easiest way is to split each line at space characters and then put them into a hash with the first column as key and the remaining 3 columns as value (in an array ref):
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
# hash which gets filled with { 'Q' => [ 20.2, 22.3, 23.4 ], ... }
my %data;
while( <DATA> ) {
my @col = split(' ', $_ );
$data{ $col[0] } = [ $col[1], $col[2], $col[3] ];
}
print Data::Dumper::Dumper(\%data);
__DATA__
F gge0001x gge0001y gge0001z
D 12-30-2006 12-30-2006 12-30-2006
T 14:15:20 14:15:55 14:16:27
S a69 a69 a69
B 15.8 16.1 15
M gge06001 gge06001 gge06001
P 30.1 29.6 29.9
Q 20.2 22.3 23.4
Output (reduced):
$VAR2 = {
'B' => [
'15.8',
'16.1',
'15'
],
'D' => [
'12-30-2006',
'12-30-2006',
'12-30-2006'
],
...
'Q' => [
'20.2',
'22.3',
'23.4'
],
...
};
Now you can access the values for Q like this:
my $first = $data{'Q'}[0];
my $second = $data{'Q'}[1];
my $third = $data{'Q'}[2];
This assumes that you have only one row starting with Q.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With