如何使用Perl读取文件中两行之间的所有行?

时间:2009-11-21 05:16:53

标签: perl

我有一个内容如下的文件:

pch
rch
channel
cap
nch
kappa
.
.
.
kary
ban
....

现在我想将我的文件从nch读取到kary并仅在其他文件中复制这些行。我怎么能在Perl中做到这一点?

5 个答案:

答案 0 :(得分:7)

如果我理解你的问题,这很简单。

    #!perl -w
    use strict;
    use autodie;

    open my $in,'<',"File1.txt";
    open my $out,'>',"File2.txt";

    while(<$in>){
    print $out $_ if /^nch/ .. /^kary/;
    }

答案 1 :(得分:3)

perlfaq6回答How can I pull out lines between two patterns that are themselves on different lines?


你可以使用Perl有点奇特的运算符(在perlop中记录):

perl -ne 'print if /START/ .. /END/' file1 file2 ...

如果你想要文字而不是线条,你可以使用

perl -0777 -ne 'print "$1\n" while /START(.*?)END/gs' file1 file2 ...

但是如果您想要嵌套出现START到END,那么您将遇到本节中有关匹配平衡文本的问题中描述的问题。

这是使用..的另一个例子:

while (<>) {
    $in_header =   1  .. /^$/;
    $in_body   = /^$/ .. eof;
# now choose between them
} continue {
    $. = 0 if eof;  # fix $.
}

答案 2 :(得分:2)

你可以在'sed'中使用它:

sed -n /nch/,/kary/p $file

您可以使用's2p'将其转换为Perl。

您也可以编写纯Perl:

while (<>)
{
    next unless /nch/;
    print;
    while (<>)
    {
        print;
        last if /kary/;
    }
}

严格来说,这两种解决方案都会打印从'nch'到'kary'的每一行。如果'nch'出现不止一次,它将打印多个代码块。这很容易解决,特别是在纯粹的Perl中('sed'解决方案留给读者练习)。

OUTER:
while (<>)
{
    next unless /nch/;
    print;
    while (<>)
    {
        print;
        last OUTER if /kary/;
    }
}

此外,解决方案寻找'nch'和'kary'作为线的一部分 - 而不是整条线。如果您需要它们匹配整行,请使用“/^nch$/”等作为正则表达式。

答案 3 :(得分:0)

类似的东西:

$filter = 0;
while (<>) {
  chomp;
  $filter = 1 if (! $filter && /^nch$/);
  $filter = 0 if ($filter && /^ban$/);
  print($_, "\n") if ($filter);
}

应该有用。

答案 4 :(得分:0)

如果您只想阅读一个块,请参阅gawk

gawk '/kary/&&f{print;exit}/nch/{f=1}f' file
Perl中的

perl -lne '$f && /kary/ && print && exit;$f=1 if/nch/; $f && print' file

while (<>) {
    chomp;
    if ($f && /kary/) {
        print $_."\n";
        last;
    }
    if (/nch/) { $f = 1; }
    print $_ ."\n" if $f;
}