我有一个看起来像这样的文件:
I,like
blah...
我想用'i,am'替换第一行来获取:
i,am
blah...
这些是大文件,所以这就是我所做的(based on this):
open(FH, "+< input.txt") or die "FAIL!";
my $header = <FH>;
chop($header);
$header =~ s/I,like/i,am/g;
seek FH, 0, 0; # go back to start of file
printf FH $header;
close FH;
但是,当我运行它时,我得到了这个:
i,amke
blah...
我看起来像是'ke'仍然存在。我该如何摆脱它?
答案 0 :(得分:7)
我会做的事情可能是这样的:
perl -i -pe 'if ($. == 1) { s/.*/i,am/; }' yourfile.txt
当当前文件句柄$.
的行计数器等于1时,这只会影响第一行。正则表达式将替换除换行符之外的所有内容。如果您需要它来匹配您的特定行,您可以在if语句中包含它:
perl -i -pe 'if ($. == 1 and /^I,like$/) { s/.*/i,am/; }' yourfile.txt
您还可以查看Tie::File
,它允许您将文件视为数组,这意味着您只需执行$line[0] = "i,am\n"
即可。但是,提到此模块可能存在性能问题。
答案 1 :(得分:3)
如果替换的长度与原始长度不同,则无法使用此技术。例如,您可以创建一个新文件,然后将其重命名为原始名称。
open my $IN, '<', 'input.txt' or die $!;
open my $OUT, '>', 'input.new' or die $!;
my $header = <$IN>;
$header =~ s/I,like/i,am/g;
print $OUT $header;
print $OUT $_ while <$IN>; # Just copy the rest.
close $IN;
close $OUT or die $!;
rename 'input.new', 'input.txt' or die $!;
答案 2 :(得分:1)
我只使用Tie::File:
#! /usr/bin/env perl
use common::sense;
use Tie::File;
sub firstline {
tie my @f, 'Tie::File', shift or die $!;
$f[0] = shift;
untie @f;
}
firstline $0, '#! ' . qx(which perl);
用法:
$ ./example
$ head -2 example
#! /bin/perl
use common::sense;