awkコマンドでgetlineを使用しても安全ですか?

awkコマンドでgetlineを使用しても安全ですか?

awkこの機能を使用してSOに回答を投稿したときに奇妙なコメントを受けましたgetlineここその答えへのリンクです。

私の回答を投稿した後、ユーザーは次のコメントを投稿しました。 (非難するものではありません。

これは良い解決策ではありません。内容に関係なく行をリンクし、必要に応じてより多くの行を処理しません。そしてgetlineの使用を避けるべきです。

getlineで関数を使用しないでくださいawk。だから私の質問は、

  • getlineawkで関数を使用しても安全ですか?
  • どのような状況で使用する必要があり、getlineどのような状況で使用してはいけませんか?
  • この機能が予期しない結果をもたらす場合は、バグレポートを送信するのはどうでしょうか?

ベストアンサー1

ほとんどの人々はgetlineそう主張する。コーディングスタイル地面。

これはawk、コードが一度に1つのレコードを処理する一般的な処理とは異なります。

getlinegetline var < "file"(またはで使用されていない場合"cmd" | getline)コードステートメントの途中に次のレコード(おそらく次のファイルから)を取得します。 NR、FNRが増加し、FILENAMEが変更される可能性があることを忘れやすいです。

これを使用するときに忘れてはならないもう1つは、EOFの場合は0を返すか、エラーの場合は<0を返すため、戻り値を確認することです。

getlineしたがって or ではありませんが、if/while (getline) ...次のようになります。

if/while ((getline) > 0) { .... }

または:

if/while ((getline < "file") > 0) {...}

ほとんどの使用は、getlineステートマシンなどのものを使用して元に戻すことができます。

変える:

/pattern/ {getline; print}

これはおそらく間違っている可能性があるため、次のように書く必要があります。

/pattern/ && (getline) > 0 {print}

あなたはこれを行います:

found_pattern {print; found_pattern=0}
/pattern/{found_pattern=1}

また、2つの方法がどのように異なるかをご覧ください。模様連続した2行に一致します。

今これを実現するだけでgetline大​​丈夫です。複数のファイルを同時に処理したい場合は、そうしてください。getlineただし、戻り値を確認することを忘れないでください。

while ((getline a < "a") > 0 && (getline b < "b") > 0) {
  ....

おすすめ記事