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

I i have tghe following data format to manipulate in @array.

17   -.500    -.119     .500    deg    4.3.2/WFOV/Vert
18   -.500    -.034     .500    deg    4.3.2/NFOV/Horiz
19   -.500    -.117     .500    deg    4.3.2/NFOV/Vert
20           -1.032    0.000    deg    4.3.3/Horizontal
21   0.000     .977             deg    4.3.3/Vertical
22    .500    1.216             deg    4.4/Horizontal
23           -1.769    -.500    deg    4.4/Vertical
24   1.000    3.300             deg    4.5/Horizontal
25           -3.265   -1.000    deg    4.5/Vertical

I need to assign six scalars representing each of the fields above. This array is just a sluped txt file.

mabye ->

foreach (@array) { my @split_array = split; my ($testnumber, $llimit, $value, $ulimit, $unit, $name) = @array; }

That is good except some of the columns are empty, either the $llimit, or the $ulimit in the data.(upper or lower limits).

This shifts my data to the left one or two places in the @split_array, and leaves me with usless mixed up scalars that are defined wrong for some of the lines.

I need it to print out like:

TestNum = $testnumber Value = $value Name = $name Ulimit = $ulimit Lli +mit = $llimit.

I have tryed to get around this without asking for help, but it has been a long day of trying diferent ideas.

Thanks in advance.

Kevin

edited: Thu Dec 4 00:21:38 2003 by jeffa - used Perl to remove   chars and br tags, added code and pre tags

Replies are listed 'Best First'.
Re: Beginner Question on splitting.
by sauoq (Abbot) on Dec 03, 2003 at 21:28 UTC

    Using split() is probably not your best bet. Since your fields seem to be fixed width, you'll do better with unpack() or, perhaps, repeated calls to substr().

    Addendum: For example, this

    my ($testnumber, $llimit, $value, $ulimit, $unit, $name) = unpack 'A9A12A12A10A8A*', $_;
    works on your sample data. You might need to clean up the variables to remove extra whitespace and such.

    -sauoq
    "My two cents aren't worth a dime.";
    
Re: Beginner Question on splitting.
by blokhead (Monsignor) on Dec 03, 2003 at 21:30 UTC
    You can use unpack to split apart fixed-width data like this:
    # assumes 5 columns, each 10 characters my $fmt = "A10" x 5; for (@array) { my ($testnumber, $llimit, $value, $ulimit, $unit, $name) = unpack($f +mt, $_); ## }
    Consult perldoc -f pack for more information. The "A" pack format will remove trailing whitespaces when unpacking. If your data is right-aligned (it's hard to tell with your variable-width font), you will have to remove leading whitespaces manually.

    blokhead

Re: Beginner Question on splitting.
by Zaxo (Archbishop) on Dec 03, 2003 at 21:41 UTC

    Is your data in fixed-width columns? It looks like it might be, and unpack is the function of choice for that.

    If it is tab delimited, instead, @split_array = split /\t/; will do the job.

    If your data file is so messy that neither is true and you have only approximate gobs of whitespace, you can try to limit the amount of whitespace you split on with something like split /\s{1,8}/; (adjusted to fit).

    Instead of slurping, why not do this line-by-line as you read the file?

    my ($testnumber, $llimit, $value, $ulimit, $unit, $name) = 0..5; while (<INFILE>) { my @split_array = split /\t/; # or whatever printf 'TestNum = %s Value = %s Name = %s Ulimit = %s Llimit = %s.', @split_array[$testnumber, $value, $name, $ulimit, $llimit]; }
    I changed the variables to hold their index in the record so they don't have to be reallocated all the time. The array slice uses those indexes to pick out the values for printf. If the numeric data gets used numerically before printing, you may want a fancier format string in printf.

    Update: ++blokhead spotted a thinko, repaired.

    After Compline,
    Zaxo

Re: Beginner Question on splitting.
by Art_XIV (Hermit) on Dec 03, 2003 at 21:30 UTC

    If your data is truly columnar then unpack is the way to go.

    Hanlon's Razor - "Never attribute to malice that which can be adequately explained by stupidity"
      substr() was the answer. Thank you.
Re: Beginner Question on splitting.
by duff (Parson) on Dec 03, 2003 at 21:37 UTC

    If your fields fit within certain columns, you could use substr() or unpack() to get the data you are interested in. Or you can break up the parsing into several stages so that the variable parts are isolated (you might want to use pattern matches with captures for this rather than split; see perlretut, perlre, and perlrequick)

Re: Beginner Question on splitting.
by TomDLux (Vicar) on Dec 03, 2003 at 21:54 UTC

    unpack will get the fields directly into the right variables (assuming you can figure out the appropriate pack encoding string .... always takes me ages). But if that weren't available, or in a slightly different situation, you could also make pack return the separator strings:

    @fields = split /(\s+)/, $_;

    $field[0] will be 17, or 18, or 19,.... $field[1] will be 7 or 19 spaces, depending on whether there is a $llimit field; similarly $field[3] or $field[5] would tell you whether you have a $ulimit field. Obviously too much post-processing in this case, but other cases may not be quite regular enough for unpack.

    postscript: Having to go back and replace square brackets with & # 0 9 1 ; and & # 0 9 3 ; should be grounds for justifiable homicide ... all I need now is to figure out who to punish.

    dead brain dept: I originally typed unpack in the code line.

    --
    TTTATCGGTCGTTATATAGATGTTTGCA