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

Hello Monks,
I am trying to parse a csv file with a single software's inventory. The file contains system name, software name and version in each line. I am writing a script to find the number of instances of each version of software based on the major and minor version numbers.

For eg: When i look for major version 10, all the following should get counted 10.00.359, 10.01.1000, 10.02.2000 When i do a numeric comparison for this in my code i get warnings during run.

Argument "10.00.359" isn't numeric in numeric le (<=) at SWCompliance.pl line **

The code snippet is given below.

$ver = 10; #loop and split the line if ($ver <= $sw_fields[2]) { $by_sw{$sw_fields[0]}{$sw_fields[2]}++; $swvercount++; }
Am i doing something wrong or is there an alternate method?
Thanks in advance.
Joseph

2006-01-17 Retitled by planetscape, as per Monastery guidelines
Original title: 'Logical Operation - Numeric vs Sting'

Replies are listed 'Best First'.
Re: Logical Operation - Numeric vs String
by ysth (Canon) on Jan 17, 2006 at 03:32 UTC
    You are using strings like "10.02.2000" as if they were numbers, so perl obligingly converts as much as it can to a number, "10.02.2000", becoming 10.02, and warns you that part of the string didn't look like part of the number.

    You could do a string match instead:

    if ($sw_fields[2] =~ /^$ver\./) # does it start with $ver and .?
    but its hard to check for major version >= 10 that way. Depending on what all you are doing, spliting up the version is probably better:
    my ($major, $minor, $subminor) = split /\./, $sw_fields[2]; if ($major >= 10)
Re: Logical Operation - Numeric vs String
by McDarren (Abbot) on Jan 17, 2006 at 03:04 UTC
    I'd be inclined to use split. For example:
    #!/usr/bin/perl -w use strict; while (<DATA>) { my ($major, $minor, $revision) = split /\./; print "Major:$major Minor:$minor Revision:$revision\n"; # Do other processing here } __DATA__ 10.00.359 10.01.1000 10.02.2000

    You can then use $major in whatever comparisons you want, store it in a hash, or whatever.

    Note that the period (.) must be escaped in the split match, otherwise it would be taken to mean "any character".

    Hope this helps,
    Darren :)

Re: Logical Operation - Numeric vs String
by Old_Gray_Bear (Bishop) on Jan 17, 2006 at 03:05 UTC
    While your data is composed solely of the ten numerals and periods, it isn't numeric in the sense of numeric versus string because there is more than one period in the string. Numeric data only hase one decimal point.

    ----
    I Go Back to Sleep, Now.

    OGB

Re: Logical Operation - Numeric vs Sting
by reasonablekeith (Deacon) on Jan 17, 2006 at 11:42 UTC
    It's probably the multiple decimal places that are causing the problem, perl is recognising the value as a string, and giving you a warning (quite reasonably IMHO).

    your best bet is to strip the primary version number and compare that...

    $sw_fields[2] =~ m/^(\d*)/; # match the primary version if ($1 and $ver <= $1) { # do your stuff
    (untested)
    ---
    my name's not Keith, and I'm not reasonable.

    jdporter reparented from 523716

Re: Logical Operation - Numeric vs Sting
by Aristotle (Chancellor) on Jan 17, 2006 at 11:05 UTC

    I know Sting – but who are Numeric?

    :-)

    Makeshifts last the longest.

    jdporter reparented from 523716

Re: Logical Operation - Numeric vs String
by aquarium (Curate) on Jan 17, 2006 at 13:54 UTC
    numbers with dots between them are "v" or "vector" strings; not numbers. therefore you have to use string comparisons etc. i'm sure there's a module out there to compare "v" strings as version numbers....look in cpan
    the hardest line to type correctly is: stty erase ^H
Re: Logical Operation - Numeric vs Sting
by northwind (Hermit) on Jan 17, 2006 at 12:42 UTC

    Think of your version numbers as v-strings (vector strings, IIRC).  Therefore:  if(sprintf("%vd", $ver) le sprintf("%vd", $sw_fields[2])) { ... }

    This probably isn't correct as this is the first thing that came into my head and the time is early morning... :P

    jdporter reparented from 523716