0

ファイル INPUT を取得しようとしていますが、そのファイルの行に文字列が含まれている場合は、その行を別のもの (改行を含む行全体) に置き換えるか、何も置き換えません (行を削除しますそこの)。これらすべてを新しいファイルに書き込みます。

これがコードのそのセクションです...

while(<INPUT>){
    if ($_ =~ /  <openTag>/){
        chomp;
        print OUTPUT "Some_Replacement_String";
    } elsif ($_ =~ /  <\/closeTag>/) {
        chomp;
        print OUTPUT ""; #remove the line
    } else {
        chomp;
        print OUTPUT "$_\r\n"; #print the original line
    }
}

while(<INPUT>)一度に1行ずつ読み取り(私の理解が正しければ)、各行を特殊変数に保存する必要があります$_

ただし、上記のコードを実行すると、最初の if ステートメント条件が返さSome_Replacement_Stringれ、1 回だけ取得されます。(1.3m のファイルから 1 行、600,000 回の置換が予想されます)。これは明らかに私が期待する動作ではありません。ファイル全体、すべての行のコピーを取得するようなwhile(<INPUT>){print OUTPUT $_;)ことをすると、ファイル全体が読み取られていることがわかります (予想される動作)。

私がやろうとしているのは、行を取得してテストし、それを使って何かを行い、次の行に進むことです。

トラブルシューティングに役立つ場合print $.;、その while ステートメント (またはその後) のどこかで使用すると、1 が返されます。これは「最後にアクセスしたファイルハンドルの現在の行番号」であると予想しました。そのため、while ステートメントがファイル全体をループするまでには、1 ではなく、ファイル内の行数に等しくなるはずです。

このコードの他のバリエーションをいくつか試しましたが、これが最も近いと思います。期待どおりの動作が得られないのには十分な理由があると思いますが、それが何であるか教えてもらえますか?

4

1 に答える 1

4

説明している問題は、入力ファイルに 1 行しか含まれていないことを示しています。これは、次のような非常に多くの異なることが原因である可能性があります。

  • 入力レコード区切りを変更しました$/
  • 入力ファイルに正しい行末が含まれていません
  • -0777スイッチでスクリプトを実行しています

コードに関する注意事項:

if ($_ =~ /  <openTag>/){
    chomp;
    print OUTPUT "Some_Replacement_String";

使用していないラインをむさぼり食う必要はありません。

} elsif ($_ =~ /  <\/closeTag>/) {
    chomp;
    print OUTPUT "";

これはかなり冗長です。空の文字列を出力する必要はありません (実際には)、使用していない値を切り詰める必要はありません。

} else {
    chomp;
    print OUTPUT "$_\r\n"; #print the original line

改行を削除してから元に戻す必要はありません。また、通常は\n、Windows でも行末として使用します。

そして、すべての if-else 句をむさぼり食っているので、if ブロック全体の外に移動することもできます。

chomp;
if (....) {

しかし、行末が存在しないことに依存しているわけではないので、あえて使用する必要はありませんchomp

$_変数を使用する場合、 で行っているように、一部のコマンドを省略できますchomp。たとえば、単一の正規表現は次のように適用され$_ます:

} elsif (/  <\/closeTag>/) {  # works splendidly

上記のように、スラッシュを含む正規表現がある場合、スラッシュをエスケープする必要がないように、正規表現に別の区切り文字を選択できます。

} elsif (m#  </closeTag>#) {

m//ただし、前に を付けて、演算子の完全な表記を使用する必要がありますm

つまり、要するに

while(<INPUT>){
    if (/  <openTag>/){
        print OUTPUT "Some_Replacement_String";
    } elsif (m#  </closeTag>#) {
        # do nothing
    } else {
        print OUTPUT $_;   # print the original line
    }
}

そしてもちろん、最後の 2 つは、いくつかの否定ロジックを使用して 1 つに組み合わせることができます。

} elsif (not m#  </closeTag>#) {
    print OUTPUT $_;
}
于 2013-10-18T19:01:05.263 に答える