2009-06-02 47 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

相關問題