2012-12-24 56 views
1

我已經完成了這個目前爲止,但它仍然不起作用。我想打開一個文件,並在perl中替換最後一次出現的字符串模式

open (GOOD_FILE,"<$pre.XXX.XXX$post") or die "Cannot open XXX"; 

# temporarily undefine the input line separator to read the entire file at once: 
my $text = do { local $/; <GOOD_FILE> }; 
close GOOD_FILE or die $!; 
#File name to replace XXXX.XXXXX.XXXX.XXXX.CCCC where last CCCC can be  anything 
$text =~ s/^(.*\n)?XXXX\.XXXX\.XXXX\.[^\n]*/$1myname/s; 

open (GOOD_FILE,"<$pre.XXXX.XXXX$post") or die "Cannot open XXXX"; 
print GOOD_FILE $text; 
close GOOD_FILE or die $!; 

輸入文件看起來是這樣的:

I am tester testing 
I am still learning. 
XXXX.XXXX.XXXX.XXXX.CCCC 
I am tester. 
XXXX.XXXX.XXXX.XXXX.PPPP 

應該產生這樣的輸出:

I am tester testing 
I am still learning. 
XXXX.XXXX.XXXX.XXXX.CCCC 
I am tester. 
myname. 

但是我得到空文件。

謝謝你們,我能夠解決問題使用什麼替換我只是正則表達式作爲變量的變量,它工作正常。

回答

3

當您使用>模式寫入open a file時,它會自動截斷爲零長度。

可以打開兩個同時讀取和寫入文件,但不截斷它,使用+<模式,但實際上修改文件一樣,是有點棘手,因爲它需要seeking

取而代之,有兩種簡單的方法可以完成您想要的任務。如果知道該文件將永遠是相對較短,你可以將它讀入內存,修改和寫回:

my $filename = 'filename.txt'; 

open my $in, '<', $filename or die $!; 
# temporarily undefine the input line separator to read the entire file at once: 
my $text = do { local $/; <$in> }; 
close $in or die $!; 

$text =~ s/^(.*\n)?MY\.FILE\.NAME\.[^\n]*/$1myname/s; 

open my $out, '>', $filename or die $!; 
print $out $text; 
close $out or die $!; 

另一種解決方案,對於大文件,是將輸出寫入到一個臨時文件然後在完成後將臨時文件移到原始文件上。這或多或少是perl's -i switch所做的,它允許您逐行編輯任意長的文件(無論如何,只要您有足夠的磁盤空間來存儲副本)。不幸的是,在你的情況下,匹配最後使用此方法時,文件中特定字符串的出現有點棘手。

(我想你使用File::ReadBackwards,但遺憾的是沒有文件:: 向後模塊,用它去(這將是相當難寫一個,由於操作系統文件的限制,I/O接口),所以你基本上必須以相反的順序將輸出行寫入臨時文件,然後再進行第二次複製,以正確的順序將它們複製回原始文件中,這應該是可能的,但有點複雜。 )

+0

請參閱更新的代碼,如果你能幫助我,這將是偉大的。 – mysteriousboy

+0

寫入時,您需要以'>'模式打開文件,而不是'<'。此外,它看起來像你的正則表達式在'CAM'之後有一個額外的'\ .',即使在你的示例輸入中該位置沒有出現句點。最後,我非常強烈地建議用'use strict;'和'use warnings'開始你的腳本;並且解決他們產生的任何投訴;我很確定啓用了警告會告訴你第一個錯誤。 –

+0

我已經使用strick和使用警告和糾正寫模式來寫文件,但仍然不寫。這裏是我的替換$ text =〜s/^(。* \ n)?NSHT \ .FIN \ .CAM0000 \ .ESCR \ .INPUT01 \。*/$ 1myname/s; – mysteriousboy

相關問題