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

Hello Monks Can you explain to me why my code below does not work? I have a file handle open to extract a few account id's and I need to count them. Desired output

AE202B01 5

AE202B02 3

AE202B03 2

but the output comes out:

AE202B01 1

AE202B01 1

AE202B01 1

AE202B01 1

AE202B01 1

AE202B02 1

AE202B02 1

AE202B02 1

AE202B03 1

AE202B03 1

can you please tell me what is wrong

#!/usr/bin/perl use strict; use warnings; use MIME::Lite; use File::stat; use Time::localtime; use List::Util qw(sum); my $Accounts; my $count; my $counts; my $OUT; my $char; my @Accounts = ('AE202B01','AE202B02','AE202B03'); my $emd = `date --date '-30 min' +'%H'`; chop ($emd); $emd = "/tmp/pathtomyfiles/$emd.txt"; my %count; my $outfile = "/tmp/scripts/AESTUFF/AE202b.txt"; open (my $fh1, "-|" , "$emd") || die "Failed: $!\n" ; open ($OUT, "> $ +outfile") || die "Cannot open $outfile"; # temp file to which to writ +e the formated output, if there is a match while (my $line = <$fh1>) { chomp ($line); $line =~ s/ /\n/; # $line =~ s/.*UserId1://; # $line =~ s/}.*//; # $line =~ s/,pairId:.*//; if ( $line =~ /UserId1:(\w+),pairId.*/ ) { $Accounts = $1; foreach (@Accounts) { if ($Accounts =~ /$_/ ){ foreach my $str (split /\s+/, $Accounts) { $count{$str}++; } } foreach my $str (sort keys %count) { printf "%-31s %s\n", $str, $count{$str}; } } } } #} close ($OUT);

Your feedback is greatly appreciated

Replies are listed 'Best First'.
Re: Counting strings not counting correctly.
by prysmatik (Sexton) on May 10, 2017 at 20:39 UTC

    I'm too dusty to offer solid response, but the problem is in your looping structure.

    Your while should close before that last foreach. And if you're creative you can reduce those 2 foreach's in the middle to 1.

    This may do more harm than good, and probably won't run, but it should point in the right direction.

    #!/usr/bin/perl use strict; use warnings; use MIME::Lite; use File::stat; use Time::localtime; use List::Util qw(sum); my $OUT; my %Accounts = ('AE202B01'=>0, 'AE202B02'=>0, 'AE202B03'=>0); my $emd = `date --date '-30 min' +'%H'`; chop ($emd); $emd = "/tmp/pathtomyfiles/$emd.txt"; my $outfile = "/tmp/scripts/AESTUFF/AE202b.txt"; open (my $fh1, "-|" , "$emd") || die "Failed: $!\n" ; open ($OUT, "> $outfile") || die "Cannot open $outfile"; # temp file t +o which to write the formated output, if there is a match while (my $line = <$fh1>) { chomp ($line); $line =~ s/ /\n/; if ( $line =~ /UserId1:(\w+),pairId.*/ ) { foreach $accounted_account ( keys @Accounts ){ if ($accounted_account==$1){ $Accounts{$accounted_account}++; } } } } foreach my $counted (sort keys %Accounts) { printf OUT "%-31s %s\n", $counted, $Accounts{$counted}; } close ($OUT);
Re: Counting strings not counting correctly.
by johngg (Canon) on May 11, 2017 at 10:09 UTC
    my $emd = `date --date '-30 min' +'%H'`; chop ($emd); $emd = "/tmp/pathtomyfiles/$emd.txt";

    Probably better to avoid shelling out to /bin/date and use the core POSIX::strftime instead. Also, chomp would be better than chop in your original code.

    johngg@shiraz:~/perl/utils > perl -Mstrict -Mwarnings -MPOSIX=strftime + -E ' my $emd = strftime q{/tmp/pathtomyfiles/%H.txt}, localtime( time() - 1800 ); say $emd;' /tmp/pathtomyfiles/10.txt

    I hope this is of interest.

    Cheers,

    JohnGG

Re: Counting strings not counting correctly.
by LanX (Saint) on May 10, 2017 at 19:18 UTC
    Well you don't show us the input, but I doubt that you really want to print inside the $line loop.

    edit

    Besides, your indentation is bad. Which editor do you use?

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!