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

Hi, I have a file which looks like this: maps_c7 190_520 3195927 00 40 0K8632 maps_c7 210_520 3195928 00 41 0K8701 maps_c7 210_620 3195929 00 42 0K8702 maps_c7 230_560 3195930 00 43 0K8635 maps_c7 230_620 3195931 00 44 0K8703 maps_c7 230_660 3195932 00 45 0K8704 maps_c7 250_660 3195933 00 46 0K8638 maps_c7 250_800 3195934 00 47 0K8705 maps_c7 275_800 3195935 00 48 0K8640 maps_c7 300_860 3195936 00 49 0K8706 maps_c7 300_860_ER 3195937 00 50 0K8642 maps_c7 330_860_ER 3195938 00 51 0K8643 maps_c7 350_860_ER 3195939 00 52 0K8707 maps_c7 300_860_RV 3195940 00 53 0K8645 maps_c7 330_860_RV 3195941 00 54 0K8646 maps_c7 350_860_RV 3195942 00 55 0K8647 maps_c7 360_925_RV 3195943 00 56 0K9048
Depending on the columns in the file for eg: here the number of columns is 6. Each column is separated by one or more white space. so my code should look something like this,
if(column1) { $maps_dir=$_; } elsif(column2) { $dir=$_; } elsif(column3) { $part_no=$_; } elsif(column4) { $chg_lvl=$_; } elsif(column5) { $in_lock=$_; } elsif(column6) { $tspec=$_; }
What I have tried so far is this:
#!/usr/bin/perl use strict; use warnings; use Tie::File; use Fcntl; $ENV{HOME}='C:\Documents and Settings\kompeS\Desktop\PERL SCRIPTS'; my $file= "$ENV{HOME}/partno_C7_5.03.4_prod"; my @array; my $line=""; my @data; my $maps_dir=""; my $dir=""; my $part_no=""; my $chg_lvl=""; my $int_lock=""; my $t_spec=""; my @list=""; my $formatted_list=""; #### #THis is to treat the file as an array ################################ open (FILE,"$file"); close(FILE); tie (@data,'Tie::File',$file, mode=>O_RDWR) or die "Can't tie to $file +:$^E\n"; (tied @data)->defer; foreach (@data) { @list=split(/ /,@data); $formatted_list = join("<br />",@list); print "@list"; print "$formatted_list"; } (tied @data)->flush;
I am going no where with this. Please help!!! I am having trouble using split function to get each line data and process it according to the above pseudo code. Can some one help me and get me in the right direction. Thanks

Replies are listed 'Best First'.
Re: Problem with split and file processing. Need Help!!!
by jwkrahn (Abbot) on Jan 24, 2008 at 23:18 UTC
    Each column is separated by one or more white space. so my code should + look something like this,

    Why do you think it should look like that?

    $ENV{HOME}='C:\Documents and Settings\kompeS\Desktop\PERL SCRIPTS';

    Why are you using  $ENV{HOME} to store the directory name? Why not just use a normal lexical variable?

    open (FILE,"$file"); close(FILE);

    Why are you opening and then closing the file? You should always verify that the file opened correctly.

    tie (@data,'Tie::File',$file, mode=>O_RDWR) or die "Can't tie to $file +:$^E\n";

    The default mode is already O_RDWR? You should store the object returned from tie so that you can use it later for defer() and flush().

    @list=split(/ /,@data);

    split's second argument is a scalar so perl will convert @data to a scalar which will be the number of elements in @data. Since there is no whitespace in a number that has the same effect as doing  @list = scalar @data;.

    You are iterating over the array @data which means that the current line is in the  $_ variable.

    The regular expression  / / will split on a single space character, if you want to split on multiple space characters use  / +/ or just use the default  @list = split; which will split on multiple whitespace characters.

Re: Problem with split and file processing. Need Help!!!
by toolic (Bishop) on Jan 24, 2008 at 22:26 UTC
    One potential problem is that you are looping on @data, then inside the loop, you are splitting @data.

    Try relpacing:

    @list=split(/ /,@data);

    with:

    @list = split /\s+/;
Re: Problem with split and file processing. Need Help!!!
by starbolin (Hermit) on Jan 25, 2008 at 03:37 UTC

    Instead of chained ifs, you can use hash keys to index into an array.

    my %keys = qw( monster 0 hp 1 size 2 AC 3); my @data = ( [qw(troll 30 10 2)], [qw(dwarf 20 2 9 )], [qw(pixie 2 1 30 )]); foreach my $line (@data) { print "name @$line[$keys{'monster'}] \n"; print "\thas @$line[$keys{'hp'}] hit points\n"; }

    prints something like this:

    name troll has 30 hit points name dwarf has 20 hit points name pixie has 2 hit points

    Of course, by then, you're just one step away from creating objects. Which is probably a better idea in the long run.


    s//----->\t/;$~="JAPH";s//\r<$~~/;{s|~$~-|-~$~|||s |-$~~|$~~-|||s,<$~~,<~$~,,s,~$~>,$~~>,, $|=1,select$,,$,,$,,1e-1;print;redo}