dbrock has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I have a question about how to split a line into an array or hash... I have listed a small example of my ascii text file output... (The format of the ascii file has Tabs and spaces mixed with-in it But I don't seem to be able to post it with the tabs in)

Group Name A/C G F Start-Time End-time H/M/S MB +s Files L Kb/sec ====================================================================== +======================= dbweb.cloneuhn C 1 0 14 20:00:00 14 20:00:11 0/0/11 0 +.00 0 s 0.00 1 dbweb.uhn C 1 0 14 20:00:00 14 20:10:05 0/10/5 351 +.00 88 i 594.09 2 dbweb.clonedv6 C 1 0 14 21:30:00 14 21:30:08 0/0/8 0 +.00 0 s 0.00 3 dbweb.imdv C 1 0 14 17:01:00 14 22:06:05 5/5/5 10842 +4.00 101636 f 6065.35 4 dbweb.clonedv7 C 1 0 14 23:05:00 14 23:05:07 0/0/7 0 +.00 0 s 0.00 5 dbweb.clonedv2 C 1 0 14 23:10:00 14 23:10:03 0/0/3 0 +.00 0 s 0.00 6 dbweb.dv3 C 1 0 14 22:00:00 14 23:16:37 1/16/37 31002 +.00 156 i 6905.82 7 dbweb.clonedv5 C 1 0 14 23:20:00 14 23:20:03 0/0/3 0 +.00 0 s 0.00 8 dbweb.clonebaa1 C 1 0 15 13:05:00 15 13:05:03 0/0/3 0 +.00 0 s 0.00 9 dbweb.dv8 C 1 0 15 13:10:00 15 13:10:03 0/0/3 0 +.00 0 s 0.00 10 ====================================================================== +=======================

This small example is the output from a backup software tool. All of the information that I am trying to extract is listed on each line of this report... I seem to be brain dead figuring out how to split each line into an array (do I count the spaces between each element of data..?) I have captured each line that I need from the ascii file (listed in example below)...

$file = "c:\\somepath\\somefilename"; open (FILE, "<$file") or die "Cannot open $FILE for read :$!"; @lines = <FILE>; close(FILE); for($i=0;$i<@lines;$i++) { if ($lines[$i] =~ /\bdbweb./) { chomp($templine = $lines[$i]); push(@newarry, $templine); } }

I need to extract the Group name, F (failure 0 or 1), start-time, end-time, h/m/s and MB's. I was thinking that splitting each line into an array is the correct approch for extracting the required data...
Does anyone have some input to push me into the right direction..?
Thank you... Darrick...

Edit by tye, put CODE tags around fix-width text

Replies are listed 'Best First'.
Re: splitting a line into an array
by blokhead (Monsignor) on Apr 21, 2003 at 18:50 UTC
    If this is a representative sample of your data, then none of the fields have whitespace in them, so you should split on whitespace.
    my @fields = split /\s+/, $templine; # do something with $fields[0], $fields[4], etc ..
    or something more legible..
    my %record; @record{qw/group ac g f start end time mb files l kb/} = split /\s+/, $templine; # do something with $record{group}, $record{f}, $record{end}, etc..
    Another quick note: you can condense your code a lot -- iterate over the lines of the file instead of the indices:
    use strict; # hint hint my $file = 'c:\somepath\somefilename'; open (FILE, "<$file") or die "Cannot open $file for read :$!"; foreach (<FILE>) { chomp; if (/\bdbweb./) { # do stuff with $_ now } } close(FILE);

    blokhead

Re: splitting a line into an array
by perlplexer (Hermit) on Apr 21, 2003 at 18:53 UTC
    You should be able to use split();e.g.,
    $file = "c:\\somepath\\somefilename"; open (FILE, "<$file") or die "Cannot open $FILE for reading :$!\n"; while (<FILE>){ chomp; my @fields = split /\s+/; # @fields now contains individual fields from each line } close FILE;
    --perlplexer
Re: splitting a line into an array
by Limbic~Region (Chancellor) on Apr 21, 2003 at 22:35 UTC
    dbrock,
    This is how I would do it:
    #!/usr/bin/perl -w use strict; my %data; open (INPUT,"file") or die "Unable to open file : $!"; while (<INPUT>) { my @temparray = split /\s+/; next unless (@temparray == 14); $data{$temparray[0]} = \@temparray; } foreach (keys %data) { print "$_:\n"; $data{$_}->[3] ? print "\tSuccess\n" : print "\tFailure\n"; print "\tStart: $data{$_}->[5]\n"; print "\tFinish: $data{$_}->[7]\n"; print "\tH/M/S: $data{$_}->[8]\n"; print "\tMBs: $data{$_}->[9]\n"; }

    Now let me explain what is going on:

  • You have a Hash or Arrays or HoA
  • The @temparray == 14 ensures only the entries you want if keys are not unique use an AoA instead of HoA
  • You set the hash key to a reference to the array
  • You can then pull out any group and value easily

    If the group names are not going to be unique, then you can change the HoA to an Array of Arrays (AoA).

    Cheers - L~R