awkコードブロックや関数からNFで何ができますか?

awkコードブロックや関数からNFで何ができますか?

引用:awkユーティリティ用POSIX規格

私が本当に恋しいことの1つは、Perlのコマンドawkなどの区切り文字を使用して配列を接続することで、通常は即時出力を実行できることです。join

代わりに、次のようなコードを書くことになります。

for (key in array)
    joined_string = (joined_string ==  "" ? array[key] : joined_string "," array[key])

print joined_string

または

joined_string = array[1]
for (i = 2; i <= length(array); ++i)
    joined_string = joined_string "," array[i];

print joined_string

ただし、awk現在のフィールドを変更すると、次のようになります。

OFS="," # (would probably do this in BEGIN)

n = 0
for (key in array)
    $(++n) = array[key]

print

私はこれが完全に正当であると信じています。ただし、現在の入力レコードに配列内のarray項目よりも多くのフィールドがある場合、出力にゴミが生成されます(「ガベージ」は入力ファイルのデータになります)。だからこんなことができればいいと思います。

OFS = "," # (would probably do this in BEGIN)

n = 0
for (key in array)
    $(++n) = array[key]

NF = n
print

標準ではNF修正が許可されているというテキストが見つかりませんが、修正が許可されていないか未定義のアクションが呼び出されるというテキストもありません。メッセージできることがわかったgetline セットNF。だからといって、自分自身の関数やリセットコードブロックを作成できないという意味ではありませんが、NF「関数」が存在する場合にはこれを行うことをお勧めします。getline

も指摘した$0に割り当てることができますそしてこれはリセットされますNF。これは、以下のコードがより良くなるという意味ですか?

OFS = "," # (would probably do this in BEGIN)

$0 = ""
n = 0
for (key in array)
    $(++n) = array[key]

print

二重質問:

  1. 設定を許可しますかNF
  2. 最後のコードスニペットが配列を出力区切り文字に関連付ける正しい方法ですか?

ベストアンサー1

私が知る限り、そんなことはありません。基準設定の副作用に関するテキストNFだけでなく、設定を許可するかどうかも記録します。 Gawkハンドブック(次にも公開)効果的なawkプログラミング)、これは意味しますAwkを完全に記録しようとします。そしてGNUの実装だけでなく以下を含みます:

減少すると、NF新しい値NFと再計算後のフィールド値が削除されます$0。 (DC)

警告付き

警告する:一部のバージョンはawk折りたたんで再構築されません。$0NF

「(dc)」の言及はこれですAwkの「ダークコーナーズ」つまり文書化がうまくいかなかったり、まったく文書化されておらず、実装ごとに動作が異なる場合があります。

POSIX は特殊変数を次のように定義します。

で設定された変数アッ

ただし、通常、プログラムで設定できるかどうかは指定しません。一部の変数の仕様では変更可能であると言及し(参照ARGCARGV、他の変数の仕様では変更の結果が実装によって定義されると言います(ENVIRON)、他の変数では「明らかに」意図されたもの以外は何も言及しません。 。プログラムで使用されます(OFSしばらく)。

の場合、NF実験を通して答えの一部が提供されます。

  • NFGNU Awkに文書化されたタスクを修正し、mawk同じように動作します。
  • NFに変更本当のことはありません。保持されますが、$0再計算されません。

だから私は言いたい

  1. 設定は許可されますがNF、値を設定する以外は副作用がない可能性があります。
  2. 設定後$0 はいPOSIXで指定されているように、最後のバリアントは仕様に従って正確です。 (これが本当かどうかは議論の余地があります。これなったので正しい方法だ$0。 )

この機能はawkで配列を文字列に変換する方法は?興味深いですが、定義上GNU Awk拡張に依存しているので、この質問に対する答えではありません。

(やや驚くべきことに、TOTAを含めて設定できる他の変数には、およびがありますが、設定できずNR、むしろ設定すると値が消去されます。)FNRFILENAME

おすすめ記事