2009-06-02 65 views
0

我正在运行下面的代码来打开文件(测试)并编辑(搜索并替换)它。程序似乎打开文件,但不替换它会删除文件中的所有内容。我不确定为什么会这样。有人可以帮我从这里出去吗?当我尝试编辑文件时,为什么我的Perl脚本删除整个文件的内容?

#!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; 

回答

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"; 

在您发布的代码,它立即仅输出创建此文件。你应该打开文件,读取/处理内容,然后写出来。如果文件较大,则在读取旧文件时写入新文件,并在(成功)完成时替​​换旧文件。

7

open(FILE, ">filename")打开替换文件中的模式下,写了什么有以前。

另外,替代模式$replace中不能有正则表达式。

如果我理解正确的话你的意图,这可以用一个班轮

perl -pi -e 's/(\s{6}seqfile\s=\sinfil)e/${1}2/' /home/shubhi/Desktop/pamlrun/test 
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 

这可以用Perl 5.10进一步采取的\K(零宽度正向后看)的优势被缩短:

perl -pi.bak -e 's/\s{6}seqfile\s=\s\Kinfile/infil2/' testdata 
+0

我觉得领带::文件更加容易。 – Svante 2009-06-02 19:42:13

相关问题