3

我正在编写一个 perl 程序来提取我匹配的两个模式之间的行。例如下面的文本文件有 6 行。我正在匹配负载平衡器和结束。我想得到介于两者之间的 4 行。

**load balancer** 
new 
old
good
bad
**end**

我的问题是如何在负载均衡器和结束之间提取线到一个数组中。任何帮助是极大的赞赏。

4

4 回答 4

7

您可以使用触发器运算符告诉您何时处于标记之间。它还将包括实际标记,因此您需要将它们从数据收集中排除。

请注意,如果您有多个记录,这会将所有记录混合在一起,因此如果您这样做,您需要以@array某种方式存储和重置。

use strict;
use warnings;

my @array;
while (<DATA>) {
    if (/^load balancer$/ .. /^end$/) {
        push @array, $_ unless /^(load balancer|end)$/;
    }
}

print @array;

__DATA__
load balancer
new 
old
good
bad
end
于 2011-12-08T18:38:05.800 回答
2

您可以使用触发器运算符

此外,您还可以使用触发器的返回值来过滤掉边界线。返回值是一个序列号(从 1 开始),最后一个数字E0附加了字符串。

# Define the marker regexes separately, cuz they're ugly and it's easier
# to read them outside the logic of the loop.
my $start_marker = qr{^ \s* \*\*load \s balancer\*\* \s* $}x;
my $end_marker   = qr{^ \s* \*\*end\*\* \s* $}x;

while( <DATA> ) {
    # False until the first regex is true.
    # Then it's true until the second regex is true.
    next unless my $range = /$start_marker/ .. /$end_marker/;

    # Flip-flop likes to work with $_, but it's bad form to
    # continue to use $_
    my $line = $_;

    print $line if $range !~ /^1$|E/;
}

__END__
foo
bar
**load balancer** 
new 
old
good
bad
**end**
baz
biff

输出:

new 
old
good
bad
于 2011-12-08T18:39:59.073 回答
0

如果您更喜欢命令行变体:

perl -ne 'print if m{\*load balancer\*}..m{\*end\*} and !m{\*load|\*end}' file
于 2011-12-08T19:10:53.117 回答
0

对于这样的文件,我经常在记录分隔符($/$RSfrom English)中使用更改

use English qw<$RS>;
local $RS = "\nend\n";

my $record = <$open_handle>;

当你chomp这样做时,你就摆脱了那条线。

chomp( $record );
于 2011-12-08T20:06:20.960 回答