Как я могу разобрать массив с соответствующими данными на следующей строке - PullRequest
0 голосов
/ 09 февраля 2012

открыть мой $ outfile, '>', $ outpath или $ logger-> logdie ("Ошибка: не удается открыть $ outpath. Возможно, он открыт .:$!"); У меня есть команда, вывод которой читается в массив (разделить на новую строку), а затем проанализировали. Он отлично работал, когда я использовал его для извлечения из файла и просто использовал локальный $ / = ""; но я прочитал, что наличие файла-посредника расточительно, и изменил его. теперь я вообще не могу читать следующую строку !!! Вот различные типы вывода данных, которые необходимо проанализировать:

fcalias name DA540_MAE_I0032 vsan 24
pwwn X0:00:00:63:ab:03:86:e1

fcalias name NAEMS02_DH6_AUX0 vsan 53

fcalias name NRTMF02_DM3_BE0 vsan 53

fcalias name DMSRT56-777_09C0 vsan 53
interface fc2/33 swwn 20:13:ev:0d:ed:3e:da:00

когда появляется pwwn, я хочу, чтобы он был добавлен в fcalias, с переменной "type" = pwwn / swwn / none в зависимости от данных.

вот мой код,

sub fcalias 
   { my ($path, $commandfile, $switch_ip, @data) = @_;
     my $outpath = "$path${switch_ip}_${commandfile}.csv";  
     open my $outfile, '>', $outpath or $logger->logdie("Error: Can't open $outpath. It   may be open.:$!");    
     my ($type, $fcalias, $vsan);

     while  (@data) 
    { $_ = shift(@data); 
      s/^\s+//;       # Delete leading whitespaces
      next if (/^$/); # Skip empty lines

      if  (/^fcalias name (\S+) vsan (\S+)/) 
         {($fcalias, $vsan) = ($1, $2);next;} 

      elsif (/^pwwn (\S+)/) 
           {$type = "pwwn"; my $pwwn = $1; 
            print ($outfile, "$fcalias;$vsan;$type;$pwwn;;;$switch_ip\n");
           } 

      elsif  (/interface (\S+) swwn (\S+)/) 
            {$type = "interface"; 
            my ($interface,$swwn) = ($1,$2); 
            print ($outfile, "$fcalias;$vsan;$type;;$swwn;$interface;$switch_ip\n");
            } 

      else  {$type = "none";
            print ($outfile, "$fcalias;$vsan;$type;;;;$switch_ip\n");
           # print "$_ \n";
            }
    }
    print "..................DONE\n";
}

Конечно, как вы могли заметить, остальное вообще не работает, у меня fcalias double. но независимо от того, что я пытаюсь, я не могу добавить получить результат, который мне нужен. Эта подпрограмма является частью большого скрипта, который был оптимизирован и просто отсутствует эта часть ..... Помощь!

для справки, вот старый цикл кода. извините за длинный пост и форматирование кода. Я старался. Спасибо!

local $/ = "";
while (<DATA>) 
{ if  ($_ =~ m/^fcalias name (\S+) vsan (\S+)\s+pwwn (\S+)/) 
     { my ($fcalias, $vsan, $pwwn) = ($1, $2, $3);
       my $type = "pwwn";
       print (OUTFILE "$fcalias;$vsan;$type;$pwwn;;;$switch_ip\n");  
      } 

  elsif  ($_ =~ m/^fcalias name (\S+) vsan (\S+)\s+interface (\S+) swwn (\S+)/) 
      { my ($fcalias, $vsan, $interface, $swwn) = ($1, $2, $3 ,$4);
        my $type = "interface"; 
        print (OUTFILE "$fcalias;$vsan;$type;;$interface;$swwn;$switch_ip\n");
       } 

  else  ($_ =~ m/^fcalias name (\S+) vsan (\S+)/) 
       { my ($fcalias, $vsan) = ($1, $2);
         my $type = "none";
         print (OUTFILE "$fcalias;$vsan;$type;;;;$switch_ip\n");
       }
}

Ответы [ 2 ]

2 голосов
/ 09 февраля 2012

Чтобы ответить на вопрос в заголовке, вы либо

  1. Посмотрите вперед на следующую строку или

  2. Патч результата чтения предыдущей строки, когда вы читаете следующую.

Из else вообще не работает, знаете ли вы, что вы закомментировали половину этого? И что это не пишет в OUTFILE? И что ни один из ваших предоставленных входных данных не достигнет его? Вы пропускаете пустые строки и сопоставляете каждую другую строку. Выполните тело else, когда вы сопоставите ^ fcalias (или исчерпаете данные) и обнаружите, что переменные, которые он устанавливает, не были сброшены; также сбросьте эти переменные в случаях интерфейса pwwn.

Чтобы избежать промежуточного файла, но все еще использовать ваш старый код, используйте open with pipe. Например,

open DATA, "fcalias-stuff |" or die $!;
1 голос
/ 09 февраля 2012

Если чтение данных построчно делает вашу работу намного сложнее, зачем вам это?Проблема с прихлебыванием заключается в том, что все сразу попадает в память.Если ваш файл достаточно мал, это не должно быть проблемой.

Дополнительный комментарий к вашему стилю.Вы не должны использовать глобальные файловые дескрипторы (OUTFILE).Это глобальные переменные со всеми проблемами, которые идут с ними.Если у вас есть открытый с глобальным дескриптором файла в рекурсивной функции, например, вы всегда будете закрывать и снова открывать файловый дескриптор.

Лучше использовать локальные файловые дескрипторы, как в open my $outfile, '>', $outpath or die.

...