in reply to array processing

split does not happen automatically, you need to call it. If you're only trying to keep one record of each user who has logged in you could use a hash. So your loop could be:

my %user_login; while (my $line = <errlog>) { chomp $line; next unless ($line =~ /Login succeeded/); my ($date,$time,$username)=(split(' ',$line))[0,1,6]; $user_login{$username}="$date $time"; } for my $record(sort keys %user_login) { print "$record logged in at $user_login{$record}\n"; }
This will print out a sorted list of users who have logged in, along with the date/time of the last login.

Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. -- Brian W. Kernighan

Replies are listed 'Best First'.
Re^2: array processing
by Anonymous Monk on Dec 06, 2005 at 11:19 UTC
    I obviously have a lot to learn. Out of interest could this have been done with an array instead of a hash, or would it have been too messy ?

    Thanks for your help

      Yes, it would be possible, but wasteful.

      use List::MoreUtils qw(uniq); my @client_list; while (my $line = <DATA>) { chomp $line; next unless ($line =~ /Login succeeded/); push (@client_list,(split(' ',$line))[6]); } @client_list = uniq(@client_list); print join("\n",@client_list);

      Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. -- Brian W. Kernighan
        You can even do the uniqe test using grep as you add items. This is also a wasteful approach but maybe easier on memory usage if the log file that you are processing is large.
        if ($line =~ /Login succeeded. User: (\w+)/i) { my $user = $1; push @users, $user unless grep (/$user/i, @users); }
        Using a hash is the best plan.
Re^2: array processing
by Anonymous Monk on Dec 06, 2005 at 12:41 UTC
    OK having taken this on board , I decide to add a line number count so I don't go processing the same bit of the file every time this utility is run. e.g.

    my $linenum = 1; my $lastline = 200; my %user_login; while (my $line = <errlog>) { chomp $line; next unless ($linenum = $lastline); next unless ($line =~ /Login succeeded/); my ($date,$time,$username)=(split(' ',$line))[0,1,6]; $user_login{$username}="$date $time"; ++linenum; } for my $record(sort keys %user_login) { print "$record logged in at $user_login{$record}\n"; } print "line number is $linenum\n";
    This doesn't work though since $linenum is still set to 1 at the print above. How can I use the linenum variable outside the while loop to achieve this ?

      You've got an error in testing for your $linenum. Also, you're incrementing your variable after you test and loop back, so it never gets incremented. Change

      next unless ($linenum = $lastline);
      to
      next unless ($linenum++ >= $lastline);

      Update: sorry, I didn't do this carefully enough, changed to work


      Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. -- Brian W. Kernighan
        I must be doing something else wrong because it still doesn't work.
        I changed the line to
        next unless ($linenum < $lastline);
        because I want to process everything after the lastline. I still end up with linenum being set to 1 after the while loop has processed ?

        Many thanks