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