perl - 从分隔 block 中解析数据

标签 perl parsing

我有一个日志文件内容很多 block /begin CHECK ... /end CHECK 如下所示:

/begin CHECK

Var_AAA
"Description AAA"
DATATYPE UBYTE
Max_Value 255.
ADDRESS 0xFF0011

/end CHECK

/begin CHECK

Var_BBB
"Description BBB"
DATATYPE UBYTE
Max_Value 255.
ADDRESS 0xFF0022

/end CHECK
...

我想提取变量名称及其地址,然后写入一个新文件,如下所示

Name    Address
Var_AAA => 0xFF0011
Var_BBB => 0xFF0022

我只是在考虑 ($start, $keyword, $end) 来检查每个 block 并仅在关键字之后提取数据

#!/usr/bin/perl

use strict;
use warnings;

my $input  = 'input.log';
my $output = 'output.out';

my ( $start, $keyword, $end ) = ( '^\/begin CHECK\n\n', 'ADDRESS ', '\/end CHECK' );
my @block;

# open input file for reading
open( my $in, '<', $input ) or die "Cannot open file '$input' for reading: $!";

# open destination file for writing
open( my $out, '>', $output ) or die "Cannot open file '$output' for writing: $!";

print( "copying variable name and it's address from $input to $output \n" );

while ( $in ) {    #For each line of input

    if ( /$start/i .. /$end/i ) {    #Block matching
        push @block, $_;
    }

    if ( /$end/i ) {

        for ( @block ) {

            if ( /\s+ $keyword/ ) {
                print $out join( '', @block );
                last;
            }
        }

        @block = ();
    }

    close $in or die "Cannot close file '$input': $!";
}

close $out or die "Cannot close file '$output': $!";

但是执行后我什么也没得到。有人可以向我推荐示例想法吗?

最佳答案

大多数内容看起来都不错,但正是您的启动正则表达式导致了第一个问题:

'^\/begin CHECK\n\n'

您正在从文件中读取行,然后查找连续的两个换行符。这永远不会匹配,因为一行恰好以一个换行符结束(除非您更改 $/ ,但这是一个不同的主题)。如果要匹配一行的发送,可以使用$ (或 \z ) anchor :

'^\/begin CHECK$'

这是我精简的程序。您可以调整它来完成您需要做的所有其余事情:

use v5.10;
use strict;
use warnings;

use Data::Dumper;

my ($start, $keyword, $end) = (qr{^/begin CHECK$}, qr(^ADDRESS ), qr(^/end CHECK));

while (<DATA>) #For each line of input
{
    state @block;
    chomp;
    if (/$start/i .. /$end/i) #Block matching
    {
        push @block, $_ unless /^\s*$/;
    }

    if( /$end/i )
    {
        print Dumper( \@block );
        @block = ();
    }
}

之后,您将不再读取数据。您需要将文件句柄放入 <> 内(行输入运算符):

 while ( <$in> )

文件句柄将在程序结束时自动关闭。如果您想自己关闭它们也可以,但在完成之前不要这样做。不要关闭$in直到while已完成。

关于perl - 从分隔 block 中解析数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51947225/

相关文章:

C# 使用 HTML Agility Pack 解析隐藏字段

java - 在 J2ME 中解析 JSON

Perl foreach 循环遍历一个矩阵行

perl - 如何找到模块名称到不透明指针的 DynaLoader 映射?

linux - 使用错误参数的 Perl 程序

perl - 如何在 Gtk3::TreeViewColumn 中设置背景颜色?

java/JSON 未显示解析 JSON 所需的值

regex - 设置 perl 正则表达式搜索从长字符串中的给定位置开始

java - XML解析java确认

c - 在c中解析.conf文件