1
votes

Script Perl pour déterminer le nombre de connexions restantes sur le système après 16h00

J'ai un fichier de données qui affiche les données suivantes:

#!/usr/bin/perl
open(FILE, $ARGV[0]) or die ("Error Found: $!");
while ( $line = <FILE> ) {
 ($login, $time) = split('\(', $line);
#  print "Time: $time";
 ($hour,$m) = split('\:',$time);
#  print "Hour: $hour\n";
 if ( $hour <= 16 ) {
#    print "Found: $hour\n";
    $n++;
 }
}

print "There were $n logins that were still on the system after 16:00 on May 26.\n";
close(FILE);

J'ai créé un script perl qui est supposé afficher le nombre de connexions encore connectées après 16h00 le 26 mai. C'est ce que j'ai jusqu'à présent et je n'arrive pas à comprendre comment afficher le nombre correct de connexions qui sont 5.

cfs264su pts/6        x.x.x.x.x        Tue May 26 16:46 - 19:21  (02:34)
cfs264su pts/6        x.x.x.x.x        Tue May 26 16:30 - 16:46  (00:15)
cfs264su pts/6        x.x.x.x.x        Tue May 26 16:19 - 16:30  (00:10)
cfs264su pts/6        x.x.x.x.x        Tue May 26 14:59 - 15:30  (00:31)
cfs264su pts/5        x.x.x.x.x        Tue May 26 14:40 - 17:13  (02:33)
cfs264su pts/1        x.x.x.x.x        Tue May 26 14:02 - 19:06  (05:03)
cfs264su pts/6        x.x.x.x.x        Tue May 26 10:36 - 13:18  (02:41)
cfs264su pts/5        x.x.x.x.x        Tue May 26 10:22 - 12:45  (02:23)
cfs264su pts/1        x.x.x.x.x        Tue May 26 08:45 - 12:12  (03:27)
cfs264su pts/5        x.x.x.x.x        Tue May 26 00:34 - 01:28  (00:54)


5 commentaires

après devrait être 3, non? Et l'heure est le hh: mm juste après le «26 mai» ... Dans les (), c'est la durée.


C'est une mauvaise façon d'utiliser la split . Aussi, ne pas utiliser use strict; use warnings est une mauvaise idée.


J'ai oublié de mentionner que je suis très nouveau dans le script perl et c'est une question de devoir avec laquelle je me bats. Je suis complètement perdu à ce stade.


Votre logique ici est que le "temps de connexion" doit être supérieur à 16 s'ils sont toujours connectés après 16h00. Ce n'est pas vrai. Il n'y a personne avec plus de 16 heures. Vous devez vérifier l'heure de déconnexion.


Que pouvez-vous nous dire de l'apport? Est-il à largeur fixe ou séparé par des tabulations? Si c'est ce dernier, vous pouvez utiliser split pour séparer les colonnes. Si c'est le premier, vous pouvez utiliser unpack ou substr.


3 Réponses :


1
votes

J'ai enfin compris. le split devait utiliser / - /

#!/usr/bin/perl
open(FILE, $ARGV[0]) or die ("Error Found: $!");
while ( $line = <FILE> ) {
 ($login, $time) = split(/ - /, $line);
#  print "Time: $time";
 ($hour,$m) = split('/ - /:',$time);
#  print "Hour: $hour\n";
 if ( $hour < 16 ) {
#    print "Found: $hour\n";
    $n++;
 }
}

print "There were $n logins that were still on the system after 16:00 on May 26.\n";
close(FILE);

Merci!


1 commentaires

Non ... split ('/ - /:', $time) est très incorrect. Vous ne l'avez pas dans votre entrée, donc cette ligne ne fait rien. Cela fonctionne parce que l'heure de déconnexion est la première dans $time , donc l'opération < essaiera de lancer par exemple 14:40 - 17:13 (02:33) en un nombre, et se terminant par 14 , ce qui fonctionne pour vous. Je crois que je vous ai également dit d'ajouter use strict; use warnings dans votre code pour éviter de faire de simples erreurs. Apprendre Perl sans cela, c'est comme essayer de l'apprendre avec les yeux bandés.



0
votes

L'exemple de code suivant illustre l'une des manières possibles.

Algorithme:

  • convertir la date et l'heure en époque pour les délais $start et $end
  • lire les données d'entrée dans hash $record->{@fields} avec des champs comme clés
  • stocker l'enregistrement lu dans la %login HoA %login avec l' ID utilisateur comme clé
  • pour l'utilisateur d'intérêt, parcourez tous les enregistrements
  • comparer le temps de connexion avec les délais $start et $end
  • si la correspondance augmente le $count
  • imprimer $count à la fin

Courir comme:

  • script.pl user '[start]' '[end]' Linux script.pl user '[start]' '[end]'
  • script.pl user "[start]" "[end]" Windows script.pl user "[start]" "[end]"
USER:  cfs264su
START: Tue May 26 10:00:00 2020
END:   Tue May 26 15:00:00 2020
---------------------------------------------
IN:    Tue May 26 14:59:00 2020
OUT:   Tue May 26 15:30:00 2020
---------------------------------------------
IN:    Tue May 26 14:40:00 2020
OUT:   Tue May 26 17:13:00 2020
---------------------------------------------
IN:    Tue May 26 14:02:00 2020
OUT:   Tue May 26 19:06:00 2020
---------------------------------------------
IN:    Tue May 26 10:36:00 2020
OUT:   Tue May 26 13:18:00 2020
---------------------------------------------
IN:    Tue May 26 10:22:00 2020
OUT:   Tue May 26 12:45:00 2020
---------------------------------------------
Logged in: 5 times

Production

use strict;
use warnings;
use feature 'say';

use Date::Parse;

my $user  = shift || 'cfs264su';
my $start = shift || 'May 26 10:00 2020';
my $end   = shift || 'May 26 15:00 2020';

$start = date2epoch($start);
$end   = date2epoch($end);

say 'USER:  ' . $user;
say 'START: ' . scalar localtime $start;
say 'END:   ' . scalar localtime $end;
say '-' x 45;

my %login;
my @fields = qw/id pts what wday month mday in out duration/;
my $count;

while( <DATA> ) {
    my($id, $record);
    $record->@{@fields} = split "[- ()]+";
    $id = $record->{id};
    delete $record->{id};
    push @{$login{$id}}, $record;
}


for( @{$login{$user}} ) {
    my $in  = date2epoch(join ' ', $_->@{qw/month mday in/});
    my $out = date2epoch(join ' ', $_->@{qw/month mday out/});

    if( $in >= $start && $in <= $end) {
        ++$count;
        say 'IN:    ' . scalar localtime $in;
        say 'OUT:   ' . scalar localtime $out;
        say '-' x 45;
    }
}

say "Logged in: $count times";

exit;

sub date2epoch {
    my $date = shift;
    
    return str2time($date);
}

__DATA__
cfs264su pts/6        x.x.x.x.x        Tue May 26 16:46 - 19:21  (02:34)
cfs264su pts/6        x.x.x.x.x        Tue May 26 16:30 - 16:46  (00:15)
cfs264su pts/6        x.x.x.x.x        Tue May 26 16:19 - 16:30  (00:10)
cfs264su pts/6        x.x.x.x.x        Tue May 26 14:59 - 15:30  (00:31)
cfs264su pts/5        x.x.x.x.x        Tue May 26 14:40 - 17:13  (02:33)
cfs264su pts/1        x.x.x.x.x        Tue May 26 14:02 - 19:06  (05:03)
cfs264su pts/6        x.x.x.x.x        Tue May 26 10:36 - 13:18  (02:41)
cfs264su pts/5        x.x.x.x.x        Tue May 26 10:22 - 12:45  (02:23)
cfs264su pts/1        x.x.x.x.x        Tue May 26 08:45 - 12:12  (03:27)
cfs264su pts/5        x.x.x.x.x        Tue May 26 00:34 - 01:28  (00:54)


0 commentaires

0
votes

Une approche simple utilisant Time :: Piece .

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';
use Time::Piece;

# The format of the dates and times that we're dealing with
my $fmt = '%b %d %H:%M';
# Store the count
my $count;

# Get a Time::Piece object that represents our cut-off time    
my $cutoff = Time::Piece->strptime('May 26 16:00', $fmt);

# Note: I'm reading from DATA here. It's an easy way to
# prototype stuff without having to deal with opening files
while (<DATA>) {
  # Split the data on whitespace
  # Pull out columns 4, 5 and 8
  # Join them with a space - which gives us the end date/time
  my $end_str = join ' ', (split /\s+/)[4, 5, 8];

  # Parse that string into a Time::Piece object
  my $end = Time::Piece->strptime($end_str, $fmt);

  # Increment the counter if this date/time is
  # greater than the cut-off
  $count++ if $end > $cutoff;
}

say $count;

__DATA__
cfs264su pts/6        x.x.x.x.x        Tue May 26 16:46 - 19:21  (02:34)
cfs264su pts/6        x.x.x.x.x        Tue May 26 16:30 - 16:46  (00:15)
cfs264su pts/6        x.x.x.x.x        Tue May 26 16:19 - 16:30  (00:10)
cfs264su pts/6        x.x.x.x.x        Tue May 26 14:59 - 15:30  (00:31)
cfs264su pts/5        x.x.x.x.x        Tue May 26 14:40 - 17:13  (02:33)
cfs264su pts/1        x.x.x.x.x        Tue May 26 14:02 - 19:06  (05:03)
cfs264su pts/6        x.x.x.x.x        Tue May 26 10:36 - 13:18  (02:41)
cfs264su pts/5        x.x.x.x.x        Tue May 26 10:22 - 12:45  (02:23)
cfs264su pts/1        x.x.x.x.x        Tue May 26 08:45 - 12:12  (03:27)
cfs264su pts/5        x.x.x.x.x        Tue May 26 00:34 - 01:28  (00:54)


0 commentaires