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

I've been digging on Google, CPAN, and the monestary for some help. I'm trying to implement a SAS-like PROC PRINT in perl. I'm not a SAS programmer, so my explanation of PROC PRINT may be flawed.

PROC PRINT will print a neat, counted chart of an input file. For example, when reading a log file recording subsystem logons, it will print a chart containing the following headings:

LOGON DATE IP ADDRESS BEGIN TIME END TIME COUNT REASON

The bugger here is the Count function. I would like to feed perl a log file where I can count all attempted logons using a single id. For example:

xzc6548 192.168.10.5

xzc6548 192.168.10.5

xzc6548 192.168.10.10

These fields, along with the others omitted would be printed as follows:

LOGON -- IP -- CNT ........

xzc6548 -- 192.168.10.5 -- 2 ........

xzv6548 -- 192.168.10.10 -- 1 ........

I've been working with perl and log files for a while now, but getting to this level of output escapes me right now.

Any suggestions?

Monger +++++++++++++++++++++++++ Munging Perl on the side

Replies are listed 'Best First'.
Re: Perl equivalent to SAS PROC PRINT
by si_lence (Deacon) on Jan 05, 2005 at 16:09 UTC
    Hi
    for counting unique things, hashes are your friends.
    This does not produce excatly what you showed but it should
    get you started (I hope)
    use strict; use warnings; my %ch; while (<DATA>) { chomp; my ($logon, $ip) = split; $ch{"$logon -- $ip"}++; } foreach my $key (keys %ch) {print "$key -- $ch{$key}\n"}; __DATA__ xzc6548 192.168.10.5 xzc6548 192.168.10.5 xzc6548 192.168.10.10

    BTW. SAS Proc print does not do the coundting, you would
    have to use a Proc Freq for this.
    si_lence
Re: Perl equivalent to SAS PROC PRINT
by osunderdog (Deacon) on Jan 05, 2005 at 16:03 UTC

    If I understand your quandry correctly, you need a composite key made up of both LOGON and IP:

    use strict; my $bag; while(<DATA>) { chomp; my @data = split; if(exists $bag->{"$data[0] -- $data[1]"}) { $bag->{"$data[0] -- $data[1]"}->[0]++; } else { $bag->{"$data[0] -- $data[1]"} = [1, @data]; } } print(" LOGON -- IP -- CNT ........\n"); while(my($key,$value) = each(%$bag)) { my ($count, $login, $ip) = @$value; printf("%8s -- %17s -- %04d ...\n", $login, $ip, $count); } __DATA__ xzc6548 192.168.10.5 xzc6548 192.168.10.5 xzc6548 192.168.10.10

    UPDATE: Changed some strange line endings.


    "Look, Shiny Things!" is not a better business strategy than compatibility and reuse.

Re: Perl equivalent to SAS PROC PRINT
by xdg (Monsignor) on Jan 05, 2005 at 18:40 UTC

    For some practical examples of this kind of thing with reference to log files (or a ready-made solution, depending on what your needs are), check out the source code to logwatch, a very nicely done log scanner/reporting program written in perl. I actually got started with perl years ago learning how to tweak logwatch for my own system.

    -xdg

    Code posted by xdg on PerlMonks is public domain. It has no warranties, express or implied. Posted code may not have been tested. Use at your own risk.