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

Here I am trying to count the events where 10th field (Submit), 13th field (GSM), 14th field (SMPP). The sample input is

Tue Oct 13 00:50:01 2015|1025|959791769374|1234|Tue Oct 13 00:50:01 20 +15|Tue Oct 13 00:50:01 2015|CMT|Undelivered|none|Submit|0|SMSC_PR_LC_ +SMSC_InvalidDestAddress|GSM|INVALID|ASCII|92|92|no||no|no||None|No|NO +|no|no|0|0|0|0||959790000028||8|0||0|no|no|default_billing|-1|0|no|no +|1|1|1|1|0|1|0|0|||||Tue Oct 13 06:50:01 2015|SR|||IV|011809614446740 +010007|||0|0||0|0||0||||1234||||||||||||||||||

I tried like this. It's not showing any error nor warnings. I don't understand where I have to mention my input file.

#!/usr/bin/perl use strict; use warnings; use Text::CSV; my $csv = Text::CSV->new(); # create a new object $csv->setDelimiter('|'); my $sample_input_string = '""|""|""|""|""|""|""|""|Submit|""|""|""|GSM +|GSM|'; if ($csv->parse($sample_input_string)) { my @field = $csv->fields; my $count = 0; for my $column (@field) { print ++$count, " => ", $column, "\n"; } print "\n"; } else { my $err = $csv->error_input; print "parse() failed on argument: ", $err, "\n"; }

Output

[root@ems Telenor_CDR]# perl text_csv.pl 1 => 2 => 3 => 4 => 5 => 6 => 7 => 8 => 9 => 10 => 11 => 12 => 13 => 14 => 15 => 16 => 17 => 18 => 19 => 20 => 21 => 22 => 23 => 24 => 25 => 26 => 27 =>

Expected output

Submit|GSM|GSM => 560

Replies are listed 'Best First'.
Re: Need help with Text::CSV
by Tux (Canon) on Oct 28, 2015 at 07:33 UTC

    You can also use a recent version of Text::CSV_XS (not one from 2006), and use the csv function:

    use Text::CSV_XS qw(csv); my $count = 0; my $aoa = csv (in => "sample.csv", sep => "|", filter => { 10 => sub { $_ eq "Submit" }, 13 => sub { $_ eq "GSM" }, 14 => sub { $_ eq "SMPP" and ++$count }, }); say $count;

    Enjoy, Have FUN! H.Merijn
Re: Need help with Text::CSV
by kevbot (Vicar) on Oct 28, 2015 at 05:42 UTC
    Hi ravi45722,

    Please post the code that you are actually running. If I run your script, I get this output:

    Can't locate method setDelimiter at rb.pl line 8.
    The documentation for Text::CSV states that this is how one defines the delimiter,
    my $csv = Text::CSV->new({ sep_char => '|' });
    So, here is a slightly modified version of your script.
    #!/usr/bin/perl use strict; use warnings; use Text::CSV; my $csv = Text::CSV->new({ sep_char => '|' }); # create a new object my $sample_input_string = '""|""|""|""|""|""|""|""|Submit|""|""|""|GSM +|GSM|'; if ($csv->parse($sample_input_string)) { my @field = $csv->fields; my $count = 0; for my $column (@field) { print ++$count, " => ", $column, "\n"; } print "\n"; } else { my $err = $csv->error_input; print "parse() failed on argument: ", $err, "\n"; }
    The output is:
    1 => 2 => 3 => 4 => 5 => 6 => 7 => 8 => 9 => Submit 10 => 11 => 12 => 13 => GSM 14 => GSM 15 =>
    I'm not sure why you expect your output to be:
    Submit|GSM|GSM => 560
    as that does not seem consistent with your script or your input data.

      I posted my code as it is. And I got that  $csv->setDelimiter('|'); from http://search.cpan.org/~erangel/Text-CSV/CSV.pm. I posted my requirement above. Is it possible to read a file and group as per my conditions through this module??

        The link you posted is to a very old (2006) version of Text::CSV. It was also marked as an UNAUTHORIZED RELEASE. If you are using a more recent version of Text::CSV, the following should work to count the records that satisfy your criteria:
        #!/usr/bin/perl use strict; use warnings; use Text::CSV; my $csv = Text::CSV->new({ sep_char => '|' }); open my $fh, "<", "ravi.csv" or die "ravi.csv: $!"; my $count = 0; while (my $row = $csv->getline($fh)){ my @fields = @{$row}; if($fields[9] eq 'Submit' and $fields[12] eq 'GSM' and $fields[13] + eq 'SMPP'){ ++$count; } } print "Count is: $count\n"; exit;