[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 408
  • Last Modified:

Create hash array from other array and create csv file with new data.

Hey,

I did some disk usage calculations and added the results into an array. So now I have an array that looks like this:

du_out[0] =  185 MB   /foo/bar/
du_out[1] =  100MB    /foo/bar/text.file
du_out[2] =  85MB      /foo/bar/other.txt
 etc.

I want to create a csv file with that array using the Text:CSV module. Not really a necessity to use it I just thought it'd be easier with the module. Anyway, I want each row of the csv file to have the size in the first column and the name in the second column.

I'm not sure how to separate the size and name from each element. Do I have to first create a hash array from the above? Is there a way to parse it straight into the csv?

Any help is appreciated. Thanks.
0
akatsuki27
Asked:
akatsuki27
  • 5
  • 5
  • 2
2 Solutions
 
farzanjCommented:
Ok, this is quick and dirty but should give you an idea


#!/usr/bin/perl


$du_out[0] =  "185 MB   /foo/bar/";
$du_out[1] =  "100MB    /foo/bar/text.file";
$du_out[2] =  "85MB      /foo/bar/other.txt";

foreach $arr (@du_out)
{
    $arr =~ m/(.+MB)\s+(.+)/;
    print "Size $1";
    print "\n";

    print "File $2";
    print "\n";
}

Open in new window

0
 
farzanjCommented:
So, do you want something like this?


#!/usr/bin/perl

use warnings;
use strict;

my @du_out;
$du_out[0] =  "185 MB   /foo/bar/";
$du_out[1] =  "100MB    /foo/bar/text.file";
$du_out[2] =  "85MB      /foo/bar/other.txt";

foreach my $arr (@du_out)
{
    $arr =~ m/(.+MB)\s+(.+)/;
    print "$1,$2";
    print "\n";
}

Open in new window

0
 
JuanCarnigliaCommented:
You should, (here in pseudo code)

foreach value
     split in two, (maybe splitting right at the first "/")
     str .= trim(value1) .",". trim(value2)
     str .= "\n"
loop

I leave it up to you to investigate the actual HOW.

Greetings.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
akatsuki27Author Commented:
farzanj,

That's too specific, I'm not actually hardcoding the values. That was just an example. I'm getting the values from an array I produce on the fly with a du command.

So, the real question is, do I have to split each array element first before using the data to create the csv file or can I use what I already have to create it?

0
 
farzanjCommented:
I know this is an example.  I know you would not be working with three element array, but I showed you the entire operation.  If you chop off the array part, and change the name of array, the rest does what you want to do.

I gave you a working solution.

The answer to your question is in line

 


$arr =~ m/(.+MB)\s+(.+)/;

Open in new window

0
 
JuanCarnigliaCommented:
How about directly using:

du -h | awk '{print $1,",",$2}' > list.csv

You could also sort by size.

du -h | grep "[0-9]M" | awk '{print $1,",",$2}' > list.csv         ## Only > 1 MB and < 1GB

Greetings
0
 
akatsuki27Author Commented:
I ended up making a new array...This worked for me:

for (my $i = 0; $i <= $#du_out; $i++){
        @arr = split (' ', $du_out[$i]);
        push (@du_each, @arr);
        }

now if lets say i print "$du_each[0]\n";

the output is 185MB

--Now it should be much easier making the csv file. I assume I can use 'join' to add the commas every 2 elements right and call it 1 row? That's if I dont use the module. Please correct me if I'm wrong.
0
 
farzanjCommented:
That would work too.  My solution had saved all that effort.
0
 
akatsuki27Author Commented:
I couldn't get it work because some sizes were denoted with K.  I know very little about regex so I didnt know how to modify that to account for any size designation. This is only the 3rd perl script I've ever written and I'm not even finished.
0
 
akatsuki27Author Commented:
Another question:

I'm using the Text::CSV module but I'm getting this error:

Can't call method "getline" without a package or object reference at /usr/lib/perl5/vendor_perl/5.8.8/Text/CSV_PP.pm

Is it because I'm using it wrong? See the code below:

my $csv = Text::CSV -> new( { binary => 1 } )
                or die "Could not use CSV: ".Text::CSV -> error_diag();

open my $csv_output, '>', "/path/to/file/prep_report.csv"
        or die "Could not open CSV output file '/path/to/file/prep_report'. Exiting!";
print $csv_output "SIZE,NAME\n";

while (my $row = $csv -> getline(@du_each)){
        $row -> [2] =~ m/ [0-9]/ or next; #start new row if you match a blank space followed by a number
        push (@rows,$row);
        }
$csv -> eof or $csv -> error_diag();
close $csv_output;

Open in new window

0
 
farzanjCommented:
Two things.

You have to use the class  use IO::Handle;

You should have a scalar with getline.

REF
http://perldoc.perl.org/IO/Handle.html
0
 
akatsuki27Author Commented:
I partly accepted my own comment because I was able to answer my own question due to not being able to fully understand how to modify the expert's suggestion.

I still gave him the points though.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 5
  • 5
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now