2009-06-02 6 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"; 

置き換え、それはすぐに出力のみのため、このファイルを作成します。ファイルを開き、内容を読み込み、処理してから書き出す必要があります。ファイルがかなり大きい場合は、古いファイルを読むときに新しいファイルに書き込み、完了したら古いファイルを置き換えます。

1

オープン書き込み用=「>」 オープン、読み取りのために=「<」

7

open(FILE, ">filename")は、以前にあったものは何でも上書き、置換モードでファイルを開きます。

また、置換パターン$replaceで正規表現を使用することはできません。

私が正しくあなたの意図を理解している場合、これはあなたが魔法を編集するインプレースたいように見えますワンライナーで

perl -pi -e 's/(\s{6}seqfile\s=\sinfil)e/${1}2/' /home/shubhi/Desktop/pamlrun/test 
4

を置き換えることができます。あなたはおそらく[ ]をしたいよう

また
#!/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; 
} 

、あなたの正規表現の性質を考えると、それが見える:これを取得する最も簡単な方法は、@ARGVプラス<>の魔法で$^Iを使用することです(I/O Operators sectionでヌルファイルハンドルを探してください) (空白に一致する)または\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; 
} 

これは基本的に1ライナーであることを指摘していなければ私はまた悔しい思いです。

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

は、これは(ゼロ幅の正のルックビハインド)\Kを利用することにより、5.10をさらに短縮することができます。

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

私はタイが::簡単にファイルを見つけます。 – Svante

関連する問題