We help IT Professionals succeed at work.

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

akatsuki27
akatsuki27 asked
on
Medium Priority
433 Views
Last Modified: 2012-05-11
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.
Comment
Watch Question

CERTIFIED EXPERT

Commented:
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

CERTIFIED EXPERT

Commented:
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

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.

Author

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?

CERTIFIED EXPERT

Commented:
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

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
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION
CERTIFIED EXPERT

Commented:
That would work too.  My solution had saved all that effort.

Author

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.

Author

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

CERTIFIED EXPERT
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION

Author

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.
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.