我有一个内容如下的文件:
pch
rch
channel
cap
nch
kappa
.
.
.
kary
ban
....
现在我想将我的文件从nch读取到kary并仅在其他文件中复制这些行。我怎么能在Perl中做到这一点?
答案 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;
}