Perl strings into variable calculation - string

In my code I am searching for some information in bunch of log files that generate every 15 min (the time part is not so important though) and it's giving me certain output as shown below. But that's not what I want.
My end goal is to calculate the output which means I am trying to turn this string of numbers into variables and calculate the total for each restaurant, and then I want to total for all the restaurants.
Honestly I need to track these numbers and calculate the what result I need. I'm so confused with what I have so far so I need help!
I hope I made my concern clear.
Sample log file:
Total number = 0 for Mcdonalds .....somelog.java:(000)
Total number = 5 for Mcdonalds .....somelog.java:(000)
Total number = 12 for Burger King.....somelog.java:(000)
Total number = 2 for Culvers .....somelog.java:(000)
Total number = 2 for Mcdonalds.....somelog.java:(000)
Total number = 19 for culvers.....somelog.java:(000)
Total number = 0 for Mcdonalds .....somelog.java:(000)
Total number = 0 for Mcdonalds .....somelog.java:(000)
Total number = 0 for Mcdonalds .....somelog.java:(000)
Total number = 19 for culvers.....somelog.java:(000)
Total number = 0 for culvers.....somelog.java:(000)
Current output
Total number = 5 for Mcdonalds .....somelog.java:(000)
Total number = 12 for Burger King.....somelog.java:(000)
Total number = 2 for Culvers .....somelog.java:(000)
Total number = 2 for Mcdonalds.....somelog.java:(000)
Total number = 19 for culvers.....somelog.java:(000)
What I need:
Total Number for Mcdonalds = 7
Total Number for Culvers = 21
Total Number for BK = 12
Total for all = 40
Perl Code
#!/usr/bin/perl
use strict;
use warnings;
use File::Find::Rule;
use Date::Parse;
my ($dir, $type, $fh, $line, $str_1,
$str_2 );
$dir = '/dir/test/';
$type = '*';
$str_1 = 'Total Number= 0';
$str_2 = '(java:000)';
my #files = File::Find::Rule->file()->name($type)->in($dir);
open $out, '>>', "output_log" or die "Unable to open 'output_log' : $!";
print $out "\Logs \n";
print $out "--------------------------\n";
close $out or die "Unable to finish writing output_log : $!";
for my $file (#files) {
open $fh, '<', $file or die "can't open $file: $!";
open $out, '>>', "output_log" or die "Unable to open 'output_log' : $!";
while ( $line = <$fh> ) {
# Here I am searching for those which are not equal to zero
#and which has the tail java:(000)
if ( $line !~ /$str_1/ && $line =~ /$str_2/ ) {
print $out $line; #So here my output lines are all which are not zero.
}
}
close $out or die "Unable to finish writing output_log : $!";
}

I am assuming that you are getting the output as shown. So I am just focusing on the part to unify them
#!/usr/bin/perl
use strict;
use warnings;
my $string = "Total number = 5 for Mcdonalds
Total number = 12 for Burger King
Total number = 2 for Culvers
Total number = 2 for Mcdonalds
Total number = 19 for culvers";
my #rows = split("\n",$string);
my %hash = ();
foreach my $row (#rows) {
if($row =~ /(\d+)\s+for\s+(.*)$/i) {
my $comp = lc($2);
if(exists($hash{$comp})) {
$hash{$comp} = int($hash{$comp}) + int($1);
} else {
$hash{$comp} = int($1);
}
}
}
foreach (keys(%hash)) {
print $_ . "...." . $hash{$_} . "\n";
}

Related

PowerShell += on foreach loop duplicates previously added data

So i have an excel file like this
Document Number, Qty, Price
1111-01,1,3.00
1112-00A,2,4.00
And what I am doing is importing it into powershell, the going line by line.
If the quantity is ever greater than 1, I have to duplicate that line that many times whlie changing the quantity to 1 each time and updateing the document number so its unique on each line. I am then adding to an array so i can at the very end export as an excel file.
$report = Import-Excel "pathToFile.xlsx"
$report2 = #()
foreach($line in $report){
$report2+=$line.PSObject.Copy()
}
$template = #()
foreach($line in $report2)
...
some irrelevant code
...
if($line.Qty -gt 1){
$line2 = $line.PSObject.Copy()
$ogInvoice = $line2.'Document Number'.Split("-")[0]
$invoiceAfter = $line2.'Document Number'.Split("-")[1]
if($invoiceAfter -match "^*[A-Z]$"){
$letter = $invoiceAfter.Substring($invoiceAfter.Length-1,1)
}else{
$letter = ""
}
$qty = $line2.Qty
$line2.Qty = 1
$counterQty = 0
while($counterQty -lt $qty){
$invoiceLastTwoNumber = [int]('{0:d2}' -f[int] $invoiceAfter.Substring(0,2)) + $counter
$line2.'Document Number' = (-join($ogInvoice,"-",$invoiceLastTwoNumber.ToString(),$letter))
$counter = $counter + 1
$template+=$line2
$counterQty = $counterQty + 1
}
}
The problem is that after checking the progress, the first time i add the line, the document number is 1112-50A like it should be, then the next time I add the line into $template, the document number is 1112-51A but it updates the previously added line.
So i get
1111-01,1,3.00
1112-51A,1,4.00
1112-51A,1,4.00
Instead of what i want which is:
1111-01,1,3.00
1112-50A,1,4.00
1112-51A,1,4.00
NOTE: the extra coding like PSObject.Copy is other stuff i found online because apparently iterating over the $report is more like a pointer.
If I understand correctly, you're looking to repeat the current object as many times as .Qty only if .Qty is greater than 1 and in addition, update the property Value to 1.
In addition, seems like you're looking to increment the last digits of the property values of Document Number.
Leaving aside the extra code you are currently showing us and focusing only on the question being asked, this is how you could accomplish it, using $csv as an example of your source data.
$csv = #'
Document Number,Qty,Price
1111-01,1,3.00
1112-00A,2,4.00
1113-15A,4,5.00
'# | ConvertFrom-Csv
$re = [regex] '(\d+)(?=[A-Z]$)'
$output = foreach($line in $csv) {
if($line.Qty -gt 1) {
$loopCount = $line.Qty
$line.Qty = 1
for($i = 0; $i -lt $loopCount; $i++) {
$newLine = $line.PSObject.Copy()
$docNumber = $newLine.'Document Number'
$newLine.'Document Number' = $re.Replace($docNumber, {
param($s)
($i + $s.Groups[1].Value).ToString('D2')
})
$newLine
}
continue
}
$line
}
The expected output from the example $csv would be:
Document Number Qty Price
--------------- --- -----
1111-01 1 3.00
1112-00A 1 4.00
1112-01A 1 4.00
1113-15A 1 5.00
1113-16A 1 5.00
1113-17A 1 5.00
1113-18A 1 5.00

Perl Conditions

Trying to iterate through two files. Everything works although once I get to the negation of my if statement it messes everything up. The only thing that will print is the else statement
Please disregard any unused variables, when defined. Will clean it up after.
#!/usr/bin/perl
#
# Packages and modules
#
use strict;
use warnings;
use version; our $VERSION = qv('5.16.0'); # This is the version of Perl to be used
use Text::CSV 1.32; # We will be using the CSV module (version 1.32 or higher)
# to parse each line
#
# readFile.pl
# Authors: schow04#mail.uoguelph + anilam#mail.uoguelph.ca
# Project: Lab Assignment 1 Script (Iteration 0)
# Date of Last Update: Monday, November 16, 2015.
#
# Functional Summary
# readFile.pl takes in a CSV (comma separated version) file
# and prints out the fields.
# There are three fields:
# 1. name
# 2. gender (F or M)
# 3. number of people with this name
#
# This code will also count the number of female and male
# names in this file and print this out at the end.
#
# The file represents the names of people in the population
# for a particular year of birth in the United States of America.
# Officially it is the "National Data on the relative frequency
# of given names in the population of U.S. births where the individual
# has a Social Security Number".
#
# Commandline Parameters: 1
# $ARGV[0] = name of the input file containing the names
#
# References
# Name files from http://www.ssa.gov/OACT/babynames/limits.html
#
#
# Variables to be used
#
my $EMPTY = q{};
my $SPACE = q{ };
my $COMMA = q{,};
my $femalecount = 0;
my $malecount = 0;
my $lines = 0;
my $filename = $EMPTY;
my $filename2 = $EMPTY;
my #records;
my #records2;
my $record_count = -1;
my $top_number = 0;
my $male_total = 0;
my $male_count = 0;
my #first_name;
my #gender;
my #first_name2;
my #number;
my $count = 0;
my $count2 = 0;
my $csv = Text::CSV->new({ sep_char => $COMMA });
#
# Check that you have the right number of parameters
#
if ($#ARGV != 1) {
print "Usage: readTopNames.pl <names file> <course names file>\n" or
die "Print failure\n";
exit;
}
$filename = $ARGV[0];
$filename2 = $ARGV[1];
#
# Open the input file and load the contents into records array
#
open my $names_fh, '<', $filename
or die "Unable to open names file: $filename\n";
#records = <$names_fh>;
close $names_fh or
die "Unable to close: $ARGV[0]\n"; # Close the input file
open my $names_fh2, '<', $filename2
or die "Unable to open names file: $filename2\n";
#records2 = <$names_fh2>;
close $names_fh2 or
die "Unable to close: $ARGV[1]\n"; # Close the input file
#
# Parse each line and store the information in arrays
# representing each field
#
# Extract each field from each name record as delimited by a comma
#
foreach my $class_record (#records)
{
chomp $class_record;
$record_count = 0;
$count = 0;
foreach my $name_record ( #records2 )
{
if ($csv->parse($name_record))
{
my #master_fields = $csv->fields();
$record_count++;
$first_name[$record_count] = $master_fields[0];
$gender[$record_count] = $master_fields[1];
$number[$record_count] = $master_fields[2];
if($class_record eq $first_name[$record_count])
{
if($gender[$record_count] eq 'F')
{
print("$first_name[$record_count] ($record_count)\n");
}
if($gender[$record_count] eq 'M')
{
my $offset = $count - 2224;
print("$first_name[$record_count] ($offset)\n");
}
}
} else {
warn "Line/record could not be parsed: $records[$record_count]\n";
}
$count++;
}
}
#
# End of Script
#
Adam (187)
Alan (431)
Alejandro (1166)
Alex (120)
Alicia (887)
Ambrose (305)
Caleb (794)
Sample output from running the following code.
This is correct: Although if a name is not found in the second file it is supposed to say:
Adam (187)
Alan (431)
Name (0)
Alejandro (1166)
Alex (120)
Alicia (887)
Ambrose (305)
Caleb (794)
That is what the else is supposed to find. Whether the if statement returned nothing.
else {
print("$first_name[$record_count] (0)\n");
}
The output that i get when i add that else, to account for the negation is literally:
Elzie (0)
Emer (0)
Enna (0)
Enriqueta (0)
Eola (0)
Eppie (0)
Ercell (0)
Estellar (0)
It's really tough to help you properly without better information, so I've written this, which looks for each name from the names file in the master data file and displays the associated values
There's never a reason to write a long list of declarations like that at the top of a program, and you've written way too much code before you started debugging. You should write no more than three or four lines of code before you test that it works and carry on adding to it. You've ended up with 140 lines — mostly of them comments — that don't do what you want, and you're now lost as to what you should fix first
I haven't been able to fathom what all your different counters are for, or why you're subtracting a magic 2224 for male records, so I've just printed the data directly from the master file
I hope you'll agree that it's far clearer with the variables declared when they're required instead of making a huge list at the top of your program. I've dropped the arrays #first_name, #gender and #number because you were only ever using the latest value so they had no purpose
#!/usr/bin/perl
use strict;
use warnings;
use v5.16.0;
use autodie;
use Text::CSV;
STDOUT->autoflush;
if ( #ARGV != 2 ) {
die "Usage: readTopNames.pl <names file> <master names file>\n";
}
my ( $names_file, $master_file ) = #ARGV;
my #names = do {
open my $fh, '<', $names_file;
<$fh>;
};
chomp #names;
my #master_data = do {
open my $fh, '<', $master_file;
<$fh>;
};
chomp #master_data;
my $csv = Text::CSV->new;
for my $i ( 0 .. $#names ) {
my $target_name = $names[$i];
my $found;
for my $j ( 0 .. $#master_data ) {
my $master_rec = $master_data[$j];
my $status = $csv->parse($master_rec);
unless ( $status ) {
warn qq{Line/record "$master_rec" could not be parsed\n};
next;
}
my ( $name, $gender, $count ) = $csv->fields;
if ( $name eq $target_name ) {
$found = 1;
printf "%s %s (%d)\n", $name, $gender, $count;
}
}
unless ( $found ) {
printf "%s (%d)\n", $target_name, 0;
}
}
output
Adam F (7)
Adam M (5293)
Alan F (9)
Alan M (2490)
Name (0)
Alejandro F (6)
Alejandro M (2593)
Alex F (157)
Alex M (3159)
Alicia F (967)
Ambrose M (87)
Caleb F (14)
Caleb M (9143)
4 changes proposed:
foreach my $class_record (#records)
{
chomp $class_record;
$record_count = 0;
$count = 0;
# add found - modification A
my $found = 0;
foreach my $name_record ( #records2 )
{
# should not be here
#$record_count++;
if ($csv->parse($name_record))
{
my #master_fields = $csv->fields();
$record_count++;
$first_name[$record_count] = $master_fields[0];
$gender[$record_count] = $master_fields[1];
$number[$record_count] = $master_fields[2];
if($class_record eq $first_name[$record_count])
{
if($gender[$record_count] eq 'F')
{
print("$first_name[$record_count] ($record_count)\n");
}
if($gender[$record_count] eq 'M')
{
my $offset = $count - 2224;
print("$first_name[$record_count] ($offset)\n");
}
# modification B - set found =1
$found = 1;
#last; # no need to keep looping
next; # find next one if try to find more than 1
}
} else {
warn "Line/record could not be parsed: $records[$record_count]\n";
}
$count++;
}
# modification C -
if($found){
}else{
print "${class_record}(0)\n";
}
}

Perl: append numbers from one file to strings of second file

I would like to append numbers attached to (Unicode) strings in one file, to matched strings in a second file. Somehow I can't wrap my head around how to do this. Here is what my two files look like.
File 1:
दौरा, 2
प्रोत्साहन, 1
प्रगति, 4
File 2:
दौरा
dorA
प्रोत्साहन
prua2ts3Ahan
prua2ts2Ahan
prua2tsAhan
prua2t2s3Ahan
prua2t2s2Ahan
prua2t2sAhan
prOts3Ahan
prOts2Ahan
prOtsAhan
prOt2s3Ahan
prOt2s2Ahan
prOt2sAhan
प्रगति
praGat2I
praGatI
pragat2I
pragatI
The desired result would look like this:
Output:
dorA, 2
prua2ts3Ahan, 1
prua2ts2Ahan, 1
prua2tsAhan, 1
prua2t2s3Ahan, 1
prua2t2s2Ahan, 1
prua2t2sAhan, 1
prOts3Ahan, 1
prOts2Ahan, 1
prOtsAhan, 1
prOt2s3Ahan, 1
prOt2s2Ahan, 1
prOt2sAhan, 1
praGat2I, 4
praGatI, 4
pragat2I, 4
pragatI, 4
I have a hash created from File 1 that has the strings as keys, and the numbers as values. Now its a matter of matching these keys in File 2, collecting all following lines after the match, and appending the values to those following lines. Can someone point me in the right direction?
Your description of the solution is correct. Now just translate it to code:
#!/usr/bin/perl
use warnings;
use strict;
my %hash;
open my $F1, '<:encoding(UTF-8)', 'file.1' or die $!;
while (<$F1>) {
chomp;
my ($word, $num) = split /, /;
$hash{$word} = $num;
}
open my $F2, '<:encoding(UTF-8)', 'file.2' or die $!;
my $word;
while (<$F2>) {
chomp;
if (exists $hash{$_}) {
$word = $_;
} elsif ($_) {
print "$_, $hash{$word}\n";
} else {
print "\n";
}
}

Perl code using a text file

Why is my perl code not printing out anything? I have been working on this for a while now and i am using a text file which has a ton of different data which each on of my arrays are sepearated by a comma meaning it is a column.
this is my code:
#!/usr/bin/perl
open (FILE, 'census2008.txt');
my #SumLevArray;
my #StNameArray;
my #CtyNameArray;
my #PopEstimateArary;
my #BirthsArray;
my #DeathsArray;
$i = 0;
$temp = 0;
$lowestBirthRates = 100000000;
$highestBirthRates = 0;
$size = 0;
while (<FILE>)
{
chomp;
($sumlev, $stname,$ctyname,$popestimate2008,$births2008,$deaths2008) = split(",");
push (#SumLevArray, $sumlev);
push (#StNameArray, $stname);
push (#CtyNameArray, $ctyname);
push (#PopEstimateArary, $popestimate2008);
push (#BirthsArray, $births2008);
push (#DeathsArray, $deaths2008);
}
$size = #BirthsArray;
while ($i < $size)
{
if($SumLevArray[$i] == " 040"){
$temp = $BirthsArray[$i]/$PopEstimateArary[$i]/541;
if(($lowestBirthRates > $temp) &&($temp > 0)){
$lowestBirthRates = $temp;
}
if($highestBirthRates < $temp){
$highestBirthRates = $temp;
}
}
$i = $i + 1;
}
print "\n";
print "Lowest birth rate in LOW-STATE: ";
print $lowestBirthRates;
print " per 541\n";
print "Highest birth rate in HIGH-STATE: ";
print $highestBirthRates;
print " per 541\n";
print "In Washington:\n";
print " Lowest birth rate in LOW-COUNTY County, WA: x.xxx per 541\n";
print " Highest birth rate in HIGH-COUNTY County, WA: x.xxx per 541\n";
close (FILE);
exit
The best tool to help you out here is use strict; use warnings;. Make it a point to put it at the top of every script you write as it will save you a ton of time debugging trivial issues.
Here, there are a couple of is that are missing their $ sigil.
Also, consider studying the Perl data structure cookbook: perldoc perldsc. An array of hashes (technically hashrefs) would be a more scalable choice of data structure to store your data.
Beyond using Text::CSV as others have suggested, just for fun I have rewritten the code as I might have written it. It includes many of the suggestions made here and a few of my personal style choices. If you have any questions about it please ask. Also if you can post some sample data, I can check to see that it works.
#!/usr/bin/env perl
use strict;
use warnings;
my $lowestBirthRates = 100000000;
my $highestBirthRates = 0;
my $filename = 'census2008.txt';
open (my $fh, '<', $filename) or die "Cannot open $filename: $!";
my %data;
while (<$fh>) {
chomp;
my ($sumlev, $stname,$ctyname,$popestimate2008,$births2008,$deaths2008) = split(",");
push (#{$data{SumLev}}, $sumlev);
push (#{$data{StName}}, $stname);
push (#{$data{CtyName}}, $ctyname);
push (#{$data{PopEstimate}}, $popestimate2008);
push (#{$data{Births}}, $births2008);
push (#{$data{Deaths}}, $deaths2008);
}
my $i = 0;
my $size = #{$data{Births}};
while ($i < $size) {
if ( $data{SumLev}[$i] eq " 040" ){
#if ( $data{SumLev}[$i] == 40 ){
my $temp = $data{Births}[$i] / $data{PopEstimate}[$i] / 541;
if( $lowestBirthRates > $temp && $temp > 0 ){
$lowestBirthRates = $temp;
}
if ( $highestBirthRates < $temp ){
$highestBirthRates = $temp;
}
}
$i++;
}
print <<REPORT;
Lowest birth rate in LOW-STATE: $lowestBirthRates per 541
Highest birth rate in HIGH-STATE: $highestBirthRates per 541
In Washington:
Lowest birth rate in LOW-COUNTY County, WA: x.xxx per 541
Highest birth rate in HIGH-COUNTY County, WA: x.xxx per 541
REPORT
if you have the luxury of having Perl version 5.14 or greater installed, you can use an even clearer syntax, where push can take references directly, and where each can give the index in question as well as the value.
#!/usr/bin/env perl
use strict;
use warnings;
use 5.14.0;
my $lowestBirthRates = 100000000;
my $highestBirthRates = 0;
my $filename = 'census2008.txt';
open (my $fh, '<', $filename) or die "Cannot open $filename: $!";
my %data = (
SumLev => [],
StName => [],
CtyName => [],
PopEstimate => [],
Births => [],
Deaths => [],
);
while (<$fh>) {
chomp;
my ($sumlev, $stname,$ctyname,$popestimate2008,$births2008,$deaths2008) = split(",");
push ($data{SumLev}, $sumlev);
push ($data{StName}, $stname);
push ($data{CtyName}, $ctyname);
push ($data{PopEstimate}, $popestimate2008);
push ($data{Births}, $births2008);
push ($data{Deaths}, $deaths2008);
}
while (my ($i, $births) = each $data{Births}) {
if ( $data{SumLev}[$i] eq " 040" ){
#if ( $data{SumLev}[$i] == 40 ){
my $temp = $births / $data{PopEstimate}[$i] / 541;
if( $lowestBirthRates > $temp && $temp > 0 ){
$lowestBirthRates = $temp;
}
if ( $highestBirthRates < $temp ){
$highestBirthRates = $temp;
}
}
}
print <<REPORT;
Lowest birth rate in LOW-STATE: $lowestBirthRates per 541
Highest birth rate in HIGH-STATE: $highestBirthRates per 541
In Washington:
Lowest birth rate in LOW-COUNTY County, WA: x.xxx per 541
Highest birth rate in HIGH-COUNTY County, WA: x.xxx per 541
REPORT
Finally here is an implementation using Tie::Array::CSV which I wrote to be able to use a CSV file just like a 2D array in Perl (i.e. Array of ArrayRefs). It uses Text::CSV to do the parsing and Tie::File to do line access. This means that you don't need to store all the data in memory like in the previous examples.
#!/usr/bin/env perl
use strict;
use warnings;
use Tie::Array::CSV;
my $lowestBirthRates = 100000000;
my $highestBirthRates = 0;
my $filename = 'census2008.txt';
tie my #data, 'Tie::Array::CSV', $filename
or die "Cannot tie $filename: $!";
foreach my $row (#data) {
my ($sumlev, $stname, $ctyname, $popest, $births, $deaths) = #$row;
if ( $sumlev eq " 040" ){
#if ( $sumlev == 40 ){
my $temp = $births / $popest / 541;
if( $lowestBirthRates > $temp && $temp > 0 ){
$lowestBirthRates = $temp;
}
if ( $highestBirthRates < $temp ){
$highestBirthRates = $temp;
}
}
}
print <<REPORT;
Lowest birth rate in LOW-STATE: $lowestBirthRates per 541
Highest birth rate in HIGH-STATE: $highestBirthRates per 541
In Washington:
Lowest birth rate in LOW-COUNTY County, WA: x.xxx per 541
Highest birth rate in HIGH-COUNTY County, WA: x.xxx per 541
REPORT
Try:
open (FILE, 'census2008.txt') or die $!;
The open may be failing without you knowing it.
When you print something, ending it with a newline will cause it to be printed immediately, otherwise the text goes to the print buffer but the buffer is not flushed.
You should unbuffer stdout.
Add the following after #!/usr/bin/perl
$| = 1;
Having said that, here are a couple other things I would suggest:
1.) At minimum use strict; (use warnings is also advised)
Strict will force you to use "my" to declare your variables where you don't already do so. I can't tell you the number of times I've seen a programmer search and search for a bug that is easily detectable when turning on strict checking. (Typos on var names is a common one)
2.) Use the following for open
open($FILE, "<", 'census2008.txt') || die("Cannot open file!");
This will not only inform you if a file can't be opened for writing (due to the use of die),
but using $FILE instead of a raw file handle will cause the file to be closed automatically when it
goes out of scope.
Try modifying your first lines of code to:
#!/usr/bin/perl
use strict;
use warnings;
$| = 1; #
open (FILE, 'census2008.txt');
After solving the errors/warnings that are appearing, all should be ok.
To access the array you use i instead of $i as index.
Beyond this, I don't understand what you want to do inside the while loop.
There is a problem in the line:
if($SumLevArray[$i] == " 040"){
This line is evaluated to true for many values of $SumLevArray[$i] ie "40", "040", " 00040 "
if $SumLevArray[$i] is an integer, this line should be:
if($SumLevArray[$i] == 40){
if $SumLevArray[$i] is a string, this line should be:
if($SumLevArray[$i] eq " 040"){

Calculating the Mean from aPerl Script

I m still in here. ;)
I've got this code from a very expert guy, and I'm shy to ask him this basic questions...anyway this is my question now; this Perl Script prints the median of a column of numbers delimited space, and, I added some stuff to get the size of it, now I'm trying to get the sum of the same column. I did and got not results, did I not take the right column? ./stats.pl 1 columns.txt
#!/usr/bin/perl
use strict;
use warnings;
my $index = shift;
my $filename = shift;
my $columns = [];
open (my $fh, "<", $filename) or die "Unable to open $filename for reading\n";
for my $row (<$fh>) {
my #vals = split/\s+/, $row;
push #{$columns->[$_]}, $vals[$_] for 0 .. $#vals;
}
close $fh;
my #column = sort {$a <=> $b} #{$columns->[$index]};
my $offset = int($#column / 2);
my $length = 2 - #column % 2;
my #medians = splice(#column, $offset, $length);
my $median;
$median += $_ for #medians;
$median /= #medians;
print "MEDIAN = $median\n";
################################################
my #elements = #{$columns->[$index]};
my $size = #elements;
print "SIZE = $size\n";
exit 0;
#################################################
my $sum = #{$columns->[$index]};
for (my $size=0; $size < $sum; $size++) {
my $mean = $sum/$size;
};
print "$mean\n";
thanks in advance.
OK some pointers to get you going :
You can put all the numbers into an array :
my #result = split(m/\d+/, $line);
#average
use List::Util qw(sum);
my $sum = sum(#result);
You can then access individual columns with $result[$index] where index is the number of column you want to access.
Also note that :
$total = $line + $total;
$count = $count + 1;
Can be rewritten as :
$total += $line;
$count += 1;
Finally make sure that you are reading the file :
put a "debugging" print into the while loop :
print $line, "\n";
This should get you going :)

Resources