以下代码用于将文件内容从readfile复制到writefile。我想复制一些关键字,而不是复制到最后。
use strict;
use warnings;
use File::Slurp;
my @lines = read_file('readfile.txt');
while ( my $line = shift @lines) {
next unless ($line =~ m/END OF HEADER/);
last; # here suggest some other logic
}
append_file('writefile.txt', @lines);
答案 0 :(得分:5)
next
将继续循环的下一次迭代,有效地跳过该循环的循环中的其余语句(在本例中为last
)。
last
将立即退出循环,这听起来像你想要的。所以你应该能够简单地将条件语句放在last
。
另外,我不确定你为什么要将整个文件读入内存以迭代它的行?为什么不使用常规while(<>)
?我建议避免File::Slurp
,它有一些long-standing issues。
您没有显示任何带有预期输出的示例输入,并且您的描述不清楚 - 您说&#34;我想复制一些关键字&#34; 但是在您的代码中您使用shift
,它会从数组的开头中删除项目。
是否要删除之后的或 }?
此代码仅复制标题:
"END OF HEADER"
如果您要复制标题后的所有内容,则可以将上面的use warnings;
use strict;
my $infile = 'readfile.txt';
my $outfile = 'writefile.txt';
open my $ifh, '<', $infile or die "$infile: $!";
open my $ofh, '>', $outfile or die "$outfile: $!";
while (<$ifh>) {
last if /END OF HEADER/;
print $ofh $_;
}
close $ifh;
close $ofh;
替换为:
while
在看到while (<$ifh>) {
last if /END OF HEADER/;
}
while (<$ifh>) {
print $ofh $_;
}
之前,它会循环播放并执行任何操作,然后跳出第一个循环并移动到第二个循环,打印出标题后面的行。
答案 1 :(得分:1)
data.txt中:
fsffs
sfsfsf
sfSDFF
END OF HEADER
{ dsgs xdgfxdg zFZ }
dgdbg
vfraeer
代码:
use strict;
use warnings;
use 5.020;
use autodie;
use Data::Dumper;
my $infile = 'data.txt';
my $header_file = 'header.txt';
my $after_header_file = 'after_header.txt';
open my $DATA, '<', $infile;
open my $HEADER, '>', $header_file;
open my $AFTER_HEADER, '>', $after_header_file;
{
local $/ = "END OF HEADER";
my $header = <$DATA>;
say {$HEADER} $header;
my $rest = <$DATA>;
say {$AFTER_HEADER} $rest;
}
close $DATA;
close $HEADER;
close $AFTER_HEADER;
say "Created files: $header_file, $after_header_file";
输出:
$ perl 1.pl
Created files: header.txt, after_header.txt
$ cat header.txt
fsffs
sfsfsf
sfSDFF
END OF HEADER
$ cat after_header.txt
{ dsgs xdgfxdg zFZ }
dgdbg
vfraeer
$/
指定输入记录分隔符,默认情况下是换行符。因此,当您从文件中读取时:
while (my $x = <$INFILE>) {
}
$ x的每个值是一系列字符,包括输入的记录分隔符,即换行符,这是我们通常认为的文件中的一行文本。通常,我们会在文本末尾选择newline / input_record_separator:
while (my $x = <$INFILE>) {
chomp $x;
say "$x is a dog";
}
但是,您可以将输入记录分隔符设置为您想要的任何内容,例如“END OF HEADER”文本。这意味着一行将是所有文本,包括输入记录分隔符,在这种情况下是“END OF HEADER”。例如,一行将是:“abc \ ndef \ nghi \ nEND OF HEADER”。此外,chomp()
现在将从其参数的末尾删除“END OF HEADER”,因此如果您不想在输出文件中使用“END OF HEADER”标记,则可以选择行。
如果perl找不到输入记录分隔符,那么perl会一直读取文件,直到perl命中文件末尾,然后perl返回所有已读取的文本。
当您想要查找文件中的某些特定文本时,可以使用这些操作。
将变量声明为local
会使变量变得神奇:当遇到周围块的结束大括号时,perl会将变量设置回打开周围街区的支撑:
#Here, by default $/ = "\n", but some code out here could have
#also set $/ to something else
{
local $/ = "END OF HEADER";
} # $/ gets set back to whatever value it had before this block
当你改变perl的预定义全局变量之一时,只要你需要使用变量就可以改变变量,然后将变量改回原来的变量,这被认为是一种好习惯。
如果你只想在大括号之间定位文字,你可以这样做:
data.txt中:
fsffs
sfsfsf
sfSDFF
END OF HEADER { dsgs xdgfxdg zFZ }
dgdbg
vfraeer
代码段:
...
...
{
local $/ = 'END OF HEADER {';
my $pre_brace = <$DATA>;
$/ = '}';
my $target_text = <$DATA>;
chomp $target_text; #Removes closing brace
say "->$target_text<-";
}
--output:--
-> dsgs xdgfxdg zFZ <-