我正在运行以下代码来打开文件(测试)并编辑(搜索和替换)它。程序似乎打开文件,但不是替换它删除文件中的所有内容。我不确定为什么会这样。有人可以帮我从这里出去吗?
#!use/bin/perl
use strict;
use warnings;
my $line = $ARGV[0];
my $find = '\s{6}seqfile\s=\sinfile';
my $replace = '\s{6}seqfile\s=\sinfil2';
open (FILE, ">/home/shubhi/Desktop/pamlrun/test") || die "cant open file \n";
my @body = <FILE>;
foreach $line(@body)
{
(s/$find/$replace/g);
{
print FILE "$line";
}
}
close(FILE);
print "reached here\n";
exit;
答案 0 :(得分:7)
open(FILE, ">filename")
以替换模式打开文件,写下以前的文件。
此外,您无法在替换模式$replace
中使用正则表达式。
如果我理解你的意图,可以用单行
代替perl -pi -e 's/(\s{6}seqfile\s=\sinfil)e/${1}2/' /home/shubhi/Desktop/pamlrun/test
答案 1 :(得分:5)
你的open()正在打开一个文件句柄来写入你的文件。取代
open (FILE, ">/home/shubhi/Desktop/pamlrun/test") || die "cant open file \n";
与
open (FILE, "/home/shubhi/Desktop/pamlrun/test") || die "cant open file \n";
在您发布的代码中,它会立即创建此文件以仅用于输出。您应该打开文件,读取/处理内容,然后将其写出来。如果文件大小合适,则在读取旧文件时写入 new 文件,并在(成功)完成后替换旧文件。
答案 2 :(得分:4)
看起来你想要就地编辑魔术。最简单的方法是使用$^I
加上@ARGV
加上<>
的魔力(在I/O Operators section中查找空文件句柄):
#!/usr/bin/perl
use strict;
use warnings;
my $find = qr/\s{6}seqfile\s=\sinfile/;
my $replace = ' seqfile = infil2';
@ARGV = ("/home/shubhi/Desktop/pamlrun/test");
$^I = ".bak"; #safe the old files as file.bak
while (<>) {
s/$find/$replace/g;
print;
}
另外,考虑到正则表达式的性质,您可能希望[ ]
(匹配空格)或\t
(匹配标签)而不是\s
。 \s
将匹配制表符,空格和其他空格字符。
您也可以使用Tie::File
,但它似乎没有提供备份功能:
#!/usr/bin/perl
use strict;
use warnings;
use Tie::File;
my $find = qr/\s{6}seqfile\s=\sinfile/;
my $replace = ' seqfile = infil2';
tie my @lines, "Tie::File", "testdata"
or die "could not open file: $!";
for my $line (@lines) {
$line =~ s/$find/$replace/g;
}
当然,您可以使用File::Copy
滚动自己的备份:
#!/usr/bin/perl
use strict;
use warnings;
use Tie::File;
use File::Copy;
my $find = qr/\s{6}seqfile\s=\sinfile/;
my $replace = ' seqfile = infil2';
copy "testdata", "testdata.bak"
or die "could not backup file: $!";
tie my @lines, "Tie::File", "testdata"
or die "could not open file: $!";
for my $line (@lines) {
$line =~ s/$find/$replace/g;
}
perl -pi.bak -e 's/\s{6}seqfile\s=\sinfile/ seqfile = infil2/' testdata
利用\K
(零宽度正向后视),Perl 5.10可以进一步缩短这一点:
perl -pi.bak -e 's/\s{6}seqfile\s=\s\Kinfile/infil2/' testdata
答案 3 :(得分:1)
open for write ='&gt;' 打开读取='&lt;'