3

実際のファイルではなく、ファイルの最後に加えたい新しい変更をスクリプトに追加することになります。

open (INCONFIG, "+<$text") or die $!;
@config = <INCONFIG>;
foreach(@config)
{
    if ( $_ =~ m/$checker/ )
    {
        $_ = $somethingnew;
    }
print INCONFIG $_;
}
close INCONFIG or die;

最終的には、テキスト全体をもう一度書き直したかったのですが、検索条件に一致する場合は特定の文字列を変更しました。ただし、これまでのところ、ファイル全体 (変更あり) の別のコピーを古いファイルの末尾に追加するだけです。

ファイルを閉じて、別の write file -handle を使用して解析できることはわかっています。

4

4 に答える 4

1

私が理解openしているように、テキスト ファイルに読み取り/書き込みアクセスを使用することはお勧めできません。結局のところ、ファイルは単なるバイト ストリームです。ファイルの一部を別の長さのもので更新することは、頭の痛い問題です ;-)

これが私のアプローチです: -iperl の「インプレース」スイッチをエミュレートしてみてください。したがって、基本的には、後で名前を変更するバックアップ ファイルに書き込みます。(*nix システムでは、削除されたファイルを使用できるように開いているファイルハンドルを使用する魔法があるため、新しいファイルを作成する必要はありません。とにかくやってみましょう。)

my $filename = ...;
my $tempfile = "$filename.tmp";
open my $inFile,  '<', $filename or die $!;
open my $outFile, '>', $tempfile or die $!;

while (my $line = <$inFile>) {
    $line = doWeirdSubstitutions($line);
    print $outFile $line;
}

close $inFile  or die $!;
close $outFile or die $!;

rename $tempfile, $filename
  or die "rename failed: $!"; # will break under weird circumstances.

# delete temp file
unlink $tempfile or die $!;

テストされていませんが、明らかなコードです。これはあなたの問題に役立ちますか?

于 2012-07-23T12:14:36.150 に答える
0

perlopentut読み取りと書き込みの混合についてこれを言います

実際、ファイルの更新に関しては、上記の WTMP の場合のようにバイナリ ファイルで作業している場合を除き、更新にこのアプローチを使用したくないでしょう。代わりに、Perl の -i フラグが役に立ちます。

もう 1 つの方法は、Tie::Fileモジュールを使用することです。コードは次のようになります。

tie my @config, 'Tie::File', $text or die $!;

s/$checker/$somethingnew/g for @config;

ただし、プログラムをデバッグするまでは、変更する前にファイルをバックアップすることを忘れないでください。

于 2012-07-23T15:02:59.337 に答える
0

あなたの問題は、<+「更新のために開く」が何をするかについての誤解です。これについては、 Mixing Reads and Writesの Perl チュートリアルで説明されてい ます。

本当にやりたいことは、古いファイルを新しいファイルにコピーし、事後に名前を変更することです。これは、daxim によって言及されたperlfaq5で議論されています。さらに、 File::AtomicWriteなど、これを安全に行うためのモジュール全体があります。これらは、プログラムが中止され、破損したファイルが残るという問題に役立ちます。

于 2012-07-23T12:12:16.910 に答える
0

他の人が指摘したように、より良い方法があります:)

しかし、本当に を使用して読み書きしたい場合は+<、ファイルを読み取った後、ファイルの最後にいることを覚えておく必要があります...これは、出力が元のコンテンツの後に追加されることを説明しています。

あなたがする必要があるのは、以下を使用して、ファイルポインタをファイルの先頭にリセットすることですseek:

seek(INCONFIG ,0,0);

それから書き始め...

于 2012-07-23T14:18:29.580 に答える