我正在编写一个 perl 程序来提取我匹配的两个模式之间的行。例如下面的文本文件有 6 行。我正在匹配负载平衡器和结束。我想得到介于两者之间的 4 行。
**load balancer**
new
old
good
bad
**end**
我的问题是如何在负载均衡器和结束之间提取线到一个数组中。任何帮助是极大的赞赏。
我正在编写一个 perl 程序来提取我匹配的两个模式之间的行。例如下面的文本文件有 6 行。我正在匹配负载平衡器和结束。我想得到介于两者之间的 4 行。
**load balancer**
new
old
good
bad
**end**
我的问题是如何在负载均衡器和结束之间提取线到一个数组中。任何帮助是极大的赞赏。
您可以使用触发器运算符告诉您何时处于标记之间。它还将包括实际标记,因此您需要将它们从数据收集中排除。
请注意,如果您有多个记录,这会将所有记录混合在一起,因此如果您这样做,您需要以@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
您可以使用触发器运算符。
此外,您还可以使用触发器的返回值来过滤掉边界线。返回值是一个序列号(从 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
如果您更喜欢命令行变体:
perl -ne 'print if m{\*load balancer\*}..m{\*end\*} and !m{\*load|\*end}' file
对于这样的文件,我经常在记录分隔符($/
或$RS
from English
)中使用更改
use English qw<$RS>;
local $RS = "\nend\n";
my $record = <$open_handle>;
当你chomp
这样做时,你就摆脱了那条线。
chomp( $record );