使用 Perl 提取特定行

发布于 2024-12-20 09:35:31 字数 200 浏览 1 评论 0原文

我正在编写一个 perl 程序来提取我匹配的两个模式之间的行。例如下面的文本文件有 6 行。我正在匹配负载均衡器和终端。我想要得到中间的 4 条线。

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

我的问题是如何将负载均衡器和 end 之间的行提取到数组中。非常感谢任何帮助。

I am writing a perl program to extract lines that are in between the two patterns i am matching. for example the below text file has 6 lines. I am matching load balancer and end. I want to get the 4 lines that are in between.

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

My question is how do you extract lines in between load balancer and end into an array. Any help is greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

空心↖ 2024-12-27 09:35:31

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

请注意,如果您有多个记录,这会将所有记录混合在一起,因此如果您这样做,您需要以某种方式存储和重置@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

You can use the flip-flop operator to tell you when you are between the markers. It will also include the actual markers, so you'll need to except them from the data collection.

Note that this will mash together all the records if you have several, so if you do you need to store and reset @array somehow.

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
℡寂寞咖啡 2024-12-27 09:35:31

您可以使用触发器运算符

此外,您还可以使用触发器的返回值来过滤掉边界线。返回值是一个序列号(从 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

You can use the flip-flop operator.

Additionally, you can also use the return value of the flipflop to filter out the boundary lines. The return value is a sequence number (starting with 1) and the last number has the string E0 appended to it.

# 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

Outputs:

new 
old
good
bad
浮萍、无处依 2024-12-27 09:35:31

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

perl -ne 'print if m{\*load balancer\*}..m{\*end\*} and !m{\*load|\*end}' file

If you prefer a command line variation:

perl -ne 'print if m{\*load balancer\*}..m{\*end\*} and !m{\*load|\*end}' file
浅笑轻吟梦一曲 2024-12-27 09:35:31

对于这样的文件,我经常使用记录分隔符中的更改(来自 English

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

my $record = <$open_handle>;

当你chomp它时,你就摆脱了那一行。

chomp( $record );

For files like this, I often use a change in the Record Separator ( $/ or $RS from English )

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

my $record = <$open_handle>;

When you chomp it, you get rid of that line.

chomp( $record );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文