Perl-逐行读取命令输出文件
我有一个日志文件,其中包含在每台服务器上运行的几个命令的输出。格式如下Perl-逐行读取命令输出文件,perl,file,Perl,File,我有一个日志文件,其中包含在每台服务器上运行的几个命令的输出。格式如下 APRHY01> lt all 131119-15:41:39 10.105.219.68 10.0b stopfile=/tmp/27599 Checking MOM version...RNC_NODE_MODEL_M_1_200 Parsing MOM (cached): /home/ekisjay/moshell//jarxml/RNC_NODE_MODEL_M_1_200.xml.cache.gz Done
APRHY01> lt all
131119-15:41:39 10.105.219.68 10.0b stopfile=/tmp/27599
Checking MOM version...RNC_NODE_MODEL_M_1_200
Parsing MOM (cached): /home/ekisjay/moshell//jarxml/RNC_NODE_MODEL_M_1_200.xml.cache.gz Done.
.............
.
.
.
APRHY01> alt
131119-15:41:55 10.105.219.68 10.0b RNC_NODE_MODEL_M_1_200 stopfile=/tmp/27599
Connecting to 10.105.219.68:56834 (CorbaSecurity=OFF, corba_class=2, java=1.6.0_26, jacoms=R73D19, jacorb=R73D01)
Starting to retrieve active alarms
Nr of active alarms are: 3
APRHY01> strt
131119-15:41:58 10.105.219.68 10.0b RNC_NODE_MODEL_M_1_200 stopfile=/tmp/27599
Following 326 sites are up:
---------------------------------------------------------------------------------------------------------------------
MOD IUBLINK CELLNAMES CFRPHEM1 CFRPHEM2 CFRPHEM3 CFRPHEM4 CFRPHEM5 CFRPHEM6 ICDS TN ATMPORTS
---------------------------------------------------------------------------------------------------------------------
21 Iub_00023 UHYD494-X 111111 1 1 I
21 Iub_00032 UHY4100-X 111111 1 1 I
然后对于下一个服务器或节点,此操作将重复…
APRHY02> lt all
131119-15:44:51 10.105.219.4 10.0b stopfile=/tmp/2874
Checking MOM version...RNC_NODE_MODEL_M_1_200
Parsing MOM (cached): /home/ekisjay/moshell//jarxml/RNC_NODE_MODEL_M_1_200.xml.cache.gz Done.
Using paramfile /home/ekisjay/moshell//commonjars/pm/PARAM_RNC_M_1_50.txt
Parsing
file /home/ekisjay/moshell//commonjars/pm/PARAM_RNC_M_1_50.txt ...
我必须在每个节点的每个命令之间取几行(根据需求中所述的条件)。我编写了一个perl程序,逐行阅读,并在与命令匹配的每一行停止,如
/[a-Z][a-Z][a-Z][a-Z][a-Z][0-9][0-9]\>
,然后检索到下一个命令行之间和之前所需的行,并将其写入另一个文件。在循环中,我的程序实际上跳过了中间的一个命令,然后执行下一个命令(第1、第3、第5类…)。有人能帮我吗?您还没有向我们展示用于解析文件的代码,因此很难说它有什么问题:-)
要分解这样的多行日志输出,一个好方法是在文件中循环,将行附加到文本块,直到找到下一个块的第一行——然后刷新一直附加的块并创建一个新的块,从当前行开始
my $block = "";
while (<>) {
if (/[A-Z][A-Z][A-Z][A-Z][A-Z][0-9][0-9]\>/) {
write_block($block) if $block;
$block = "";
}
$block .= $_;
}
write_block($block);
my$block=”“;
而(){
如果(/[A-Z][A-Z][A-Z][A-Z][A-Z][0-9][0-9]\>/){
如果$block,则写入_block($block);
$block=“”;
}
$block.=$\uux;
}
写入块($block);
以下内容可能会有所帮助:
use strict;
use warnings;
my ( $fileName, $fh, $i );
while (<>) {
if ( !$fileName or $fileName ne $ARGV ) {
$fileName = $ARGV;
$i = 0;
}
if ( my ($cmd) = /^([A-Z]{5}\d{2}>.+)/ ) {
$cmd =~ s/\W+/_/g;
open $fh, '>', $cmd . '_' . ( sprintf '%05d', ++$i ) . '.txt' or die $!;
}
print $fh $_;
}
插入计数只是为了防止同一命令多次发送到同一服务器,因为此数字确保每个服务器都有单独的文件。
代码:
代码:my$srcFile=“new.log”;my$destFile=“developments.log”;我的={};我的$line=“”;打开(my$src,“$srcFile”)或死亡“无法打开日志文件$srcFile:$!”;打开(my$dest,“>>$destFile”)或死亡“无法打开目标文件$destFile:$!”;while($line=){if($line=){if($line=~/[A-Z][A-Z][A-Z][A-Z][A-Z][A-Z][0-9][0-9][0-9][0-9][0-9][0-9]\>/{push-happed,“命令输出的偏差:$line\n”;while line=){if($line=){if($line!~/[A-Z][A-Z][A-Z][A-Z][A-Z][A-Z][0-9][A-Z][A-Z][A-Z][A-Z][A-Z][A-;关闭$dest;收盘价$src;请考虑将代码添加到原来的问题中,以利于其他试图阅读答案的人。请准确地复制并粘贴您遇到问题的代码,以确保问题不会被任何转录错误(如
抓取的用于$抓取的)。当您的脚本遇到文件的第一行时,将出现匹配,并将空字符串传递给写入块()
@kenosis很公平,通过检查$block的计算结果是否为true,可以很容易地解决这个问题。
APRHY01_lt_all_00001.txt
APRHY01_alt_00002.txt
APRHY01_strt_00003.txt
APRHY02_lt_all_00001.txt
APRHY02_alt_00002.txt
APRHY02_strt_00003.txt
my $srcFile = "new.log";
my $destFile = "deviations.log";
my @grabbed = {};
my $line = "";
open (my $src, "$srcFile") or die "Could not open the log file $srcFile: $!";
open (my $dest, ">>$destFile") or die "Could not open the destination file $destFile: $!";
while ($line = <$src>)
{ if ($line =~ /[A-Z][A-Z][A-Z][A-Z][A-Z][0-9][0-9]\>/)
{ push @grabbed, "Deviations of the output of command: $line\n";
while ($line = <$src>)
{if ($line !~ /[A-Z][A-Z][A-Z][A-Z][A-Z][0-9][0-9]\>/)
{push @grabbed, $line;
}
else
{last;
} } }}
print $dest "\n@grabbed";
close $dest;
close $src;
LINE:
while ($line = <$src>)
{ if ($line =~ /[A-Z][A-Z][A-Z][A-Z][A-Z][0-9][0-9]\>/)
{ push @grabbed, "Deviations of the output of command: $line\n";
while ($line = <$src>)
{ if ($line !~ /[A-Z][A-Z][A-Z][A-Z][A-Z][0-9][0-9]\>/)
{ push @grabbed, $line }
else
{ redo LINE }
} } }