Частью эффективного решения проблемы является выбор правильного инструмента. В этом случае попытка сделать все это в bash, вероятно, является худшим выбором, чем что-то вроде Perl или Python, потому что:
- будет сложнее внедрять, отлаживать и поддерживать
- будет использоваться гораздо больше процессов
- производительность может быть плохой
Если вы хотите помочь написать это на более подходящем языке, просто спросите.
... позже ...
Хорошо, вы выбрали Perl….
Конечно, вы можете делать все, что пытаетесь делать в самом Perl. Однако, поскольку вы не знакомы с этим, я собрал небольшую игрушечную программу, которая должна делать то, что вам нужно.
#!/usr/bin/perl -w
use strict;
my %present;
while (<>) { # loop over input lines
if (/player \[(.*?)(?:\|\d+\.\d+\.\d+\.\d+)?\]:? (.*)/) {
my $player = $1;
my $event = $2;
if ($event eq "joined the game") {
$present{$player} = 1;
} elsif ($event eq "has left the game voluntarily") {
delete $present{$player};
} elsif ($event =~ /^was autokicked/) {
delete $present{$player};
}
}
}
foreach (sort keys %present) {
print "$_\n";
}
Полученный результат выглядит следующим образом:
$ ./analyse inputfile
Jack
Jones
Samual
и вы можете назвать это как-то так из вашего bash-скрипта:
tail -1000 ghost.log | ./analyse
или даже:
playerspresent=`tail -1000 ghost.log | ./analyse`
Я пытался сделать программу Perl настолько простой, насколько это разумно. Единственный «сложный» бит - это регулярное выражение. По сути, он проходит по входным линиям, пытаясь решить, представляет ли каждая строка кого-то, кто присоединяется или уходит. При присоединении имя пользователя добавляется в хэш %present
; если уходит, он удаляется. В конце имена перечислены в порядке.
Этого достаточно, чтобы вернуть вас на правильный путь?