Greping массив, полученный через NET:TELNET
Я пишу Munin-Pluging, и мне нравится снимать экран с сеанса Telnet. Вывод такого сеанса выглядит следующим образом:
...
0x00017 0x41b3f340 BPING 0 0 0 0 198 132 330
0x00018 0x41b47340 CHKFAILED 0 0 0 0 198 132 330
0x00026 0x41b4f340 CIP 0 0 0 0 370 264 634
0x0001e 0x41b57340 CONTROL 0 1 0 0 3876 2178 6054
0x01014 0x41b5f340 UNETSRVR 0 0 0 1 296 198 494
0x00037 0x41b67340 ---- 0 0 0 0 198 132 330
0x00000 0x43b67450 ---- 0 0 0 0 0 0 0
0x00000 0x4bb67450 ---- 0 0 0 0 5084 4224 9308
0x00000 0x49367450 ---- 0 0 0 0 14742 4158 18900
-------------------------------------------------------------------------------------------
SUMMARY : 2 40 5 7 4898229 2728176 7626405
Этот скрипт извлекает содержимое экрана в массив (@lines).
#!/usr/bin/perl
use Net::Telnet ();
use strict;
use warnings;
my $t = new Net::Telnet (Timeout => 10);
$t->port(777);
$t->open("192.168.0.1");
$t->buffer_empty;
my @lines = $t->waitfor(match =>"m/.* SUMMARY : .* \n/");
my @gagu = grep { "$_" =~ /^.*BPING.*\n/ } @lines;
print @gagu;
- К какому типу относится массив @lines?
- Почему я всегда получаю весь контент от grep, а не отфильтрованной строки?
- Отличается ли массив, полученный от net: telnet от других массивов?
Да, я новичок в Perl.
1 ответ
Я не знаком с этим модулем и с тем, что он делает, но я предполагаю, что он дает вам какое-то возвращаемое значение, подобное тому, что вы указали.
Если вы получаете все строки в вашем @gagu
массив, это может быть либо ваши данные в @lines
массив состоит только из одной строки, или что grep
выходит из строя.
Например, @lines
может содержать строку:
"foo bar baz\nfoo1 bar1 baz1\n";
и не так, как вы ожидаете
"foo bar baz\n";
"foo1 bar1 baz1\n";
Ваше утверждение grep, вероятно, работает как ожидалось, хотя вы можете рассмотреть следующие вопросы:
- Не цитирую
$_
, поскольку это не имеет смысла. - Не используется
$_
вообще, поскольку это переменная по умолчанию, ее не нужно (за исключением ясности) использовать. - Не используя якоря
^
а также\n
потому что они избыточны.
Например, ^.*
соответствует любой строке, где угодно. Использование его для простого сопоставления строки является излишним. Завершение регулярного выражения с .*\n
является избыточным, потому что все, что он говорит, это "соответствовать любому символу, кроме новой строки, пока мы не найдем новую строку". Если у вас есть переводы строк, это ничего не делает. Предполагая, что вы этого не сделаете, это дает вам ложный негатив. Все, что вам нужно для этого матча /BPING/
, Вот как может выглядеть ваш код:
use Data::Dumper;
my @lines = $t->waitfor(match =>"m/ SUMMARY :/");
my @gagu = grep /BPING/, @lines;
print Dumper \@gagu;
Если вы хотите, чтобы пропуски были распечатаны визуально, вы можете использовать $Data::Dumper::Useqq
переменная:
$Data::Dumper::Useqq = 1;
print Dumper \@gagu;
Печать переменных - очень хороший инструмент для отладки.