Re: defined on hash value does not work in my code :(



saffy wrote:
Apologies for posting the whole program but I can't see where I am
going wrong, I have tried several things to get the following line to
work, but it appears to be broken:-

    $cts + 1 if not
defined($db{$months}{$days}{$computernames}{$next});

$cts is never incremented even if there is no defined key->value pair
for $db{$months}{$days}{$computernames}{$next}.

That's because you're not actually incrementing $cts. Try:

$cts += 1 if not defined();

or

++$cts if not defined();

instead.
HTH
Chris.


I am new to perl and this is only my second program, I would appreciate some advice from more experienced perl people.

Many Thanks


====== code follows ======

#!/usr/bin/perl

use strict 'vars';

my %db;
my %ip2computer;
my %suspectipmapping;
my %usernamebyhour;
my %datesortorder = (Jan => '1', Feb => '2', Mar => '3', Apr => '4',
May => '5', Jun => '6', Jul => '7',
  Aug => '8', Sep => '9', Oct => '10', Nov => '11', Dec => '12', 1 =>
'13', 2 => '14', 3 => '15',
  4 => '16', 5 => '17', 6 => '18', 7 => '19', 8 => '20', 9 => '21', 10
=> '22', 11 => '23', 12 => '24',
  13 => '25', 14 => '26', 15 => '27', 16 => '28', 17 => '29', 18 =>
'30', 19 => '31', 20 => '32',
  21 => '33', 22 => '34', 23 => '35', 24 => '36', 25 => '37', 26 =>
'38', 27 => '39', 28 => '40',
  29 => '41', 30 => '42', 31 => '43', );

sub bydate {
  $datesortorder{$a} <=> $datesortorder{$b}
};

while (<>) {
        if (/^(\w+)\s+(\w+)\s+(\d\d):(\d\d):(\d\d)\s+.*\]\s+540\s+.*
        User\sName:(\S+)\$.*Network\s+Address:

(?!172\.20\.\d+\.\d+|172\.21\.20\.\d+|172\.21\.24\.\d+|127\.\d+\.\d+\.\d+)
        (\d+\.\d+\.\d+\.\d+).*$/ix) {
    my $month = "$1";
    my $day = "$2";
    my $hour = "$3";
    my $minute = "$4";
    my $second = "$5";
    my $computername = uc("$6");
    my $netaddress = "$7";
    $db{$month}{$day}{$computername}{$hour} = "$hour";   # capture
hours on for computer
    if (defined($ip2computer{$month}{$day}{$hour}{$netaddress})
        && $ip2computer{$month}{$day}{$hour}{$netaddress} ne
$computername) {
      $suspectipmapping{$ip2computer{$month}{$day}{$hour}{$netaddress}}
= 1;
      $suspectipmapping{$computername} = 1;
    }
    else {
      $ip2computer{$month}{$day}{$hour}{$netaddress} = $computername;
    }
  }
  if (/^(\w+)\s+(\w+)\s+(\d\d):(\d\d):(\d\d)\s+.*\]\s+673\s+.*
        User\s+Name:\s*(?!\S+\$\@)(\S+)\@.*Client\s+Address:

(?!172\.20\.\d+\.\d+|172\.21\.20\.\d+|172\.21\.24\.\d+|127\.\d+\.\d+\.\d+)
        (\d+\.\d+\.\d+\.\d+).*$/ix) {
        my $month = "$1";
        my $day = "$2";
        my $hour = "$3";
        my $minute = "$4";
        my $second = "$5";
        my $username = lc("$6");
        my $netaddress = "$7";
        unless
($usernamebyhour{$month}{$day}{$hour}{$ip2computer{$month}{$day}{$hour}{$netaddress}}
                =~ /($username)/i) {

$usernamebyhour{$month}{$day}{$hour}{$ip2computer{$month}{$day}{$hour}{$netaddress}}
.= "$username "
        }
  }
}

#print "Report for domain PCs that communicated with domain
controllers, along with
#users who logged onto those PCs at least once.\n\n";

foreach my $months (sort bydate keys %db) {
    foreach my $days (sort bydate keys %{$db{$months}}) {
        #print "\n$months $days\n";
        foreach my $computernames (sort keys %{$db{$months}{$days}}) {
            printf "%s,%s,%s,", ($months,$days,$computernames);
            my @times1;
            my @times2;
            my @times3;
            my @times4;
            my @users;
            foreach my $hours qw/00 01 02 03 04 05 06 07 08 09 10 11 12
13 14 15 16 17 18 19 20 21 22 23/ {
                my $previous = sprintf("%0.2d\n", ($hours - 1)) unless
$hours eq "00";
                my $next = sprintf("%0.2d\n", ($hours + 1)) unless
$hours eq "23";
                my $cts = 1; # current time slot
                @times1[$#times1 + 1] = sprintf "%s",
$db{$months}{$days}{$computernames}{$hours}
                    if ($db{$months}{$days}{$computernames}{$hours}
                            && $cts == 1);
                @times2[$#times2 + 1] = sprintf "%s",
$db{$months}{$days}{$computernames}{$hours}
                    if ($db{$months}{$days}{$computernames}{$hours}
                            && $cts == 2);
                @times3[$#times3 + 1] = sprintf "%s",
$db{$months}{$days}{$computernames}{$hours}
                    if ($db{$months}{$days}{$computernames}{$hours}
                            && $cts == 3);
                @times4[$#times4 + 1] = sprintf "%s",
$db{$months}{$days}{$computernames}{$hours}
                    if ($db{$months}{$days}{$computernames}{$hours}
                            && $cts == 4);

### The following line does not appear to work
                $cts + 1 if not
defined($db{$months}{$days}{$computernames}{$next});
                @users[$#users + 1] = sprintf "%s",
$usernamebyhour{$months}{$days}{$hours}{$computernames}
                    if
$usernamebyhour{$months}{$days}{$hours}{$computernames};
            };
            printf "%s,%s,", @times1[0,$#times1];
            printf "%s,%s,", @times2[0,$#times2];
            printf "%s,%s,", @times3[0,$#times3];
            printf "%s,%s,", @times4[0,$#times4];
            chop @users;
            printf "%s,%s", @users[0,$#users];
            print "\n";
        }
        #print "\nDaily total number of PCs: " .
keys(%{$db{$months}{$days}}) . "\n";
    }
}

.