awkで中括弧の内部割り当てと中括弧の外部割り当て

awkで中括弧の内部割り当てと中括弧の外部割り当て

~からこの問題、私は次の解決策で答えた。

awk 'FNR==NR{a[FNR]=$2;next}{$NF=a[FNR]}1' file2 file1

期待どおりに動作します。

しかし、私の心に浮かぶ最初の解決策は次のとおりです。

$ awk 'FNR==NR{a[FNR]=$2;next}$NF=a[FNR]' file2 file1
A 63 9 6
B 45 3 5

awkwhenが最初の行を印刷しないため、機能しませんfile1。これは私を驚かせ、なぜawk最初の行をスキップするのかわかりません。

ここにいくつかの例があります。

$ awk 'FNR==NR{next}$1=123' file2 file1 
123 23 8 T
123 63 9 9
123 45 3 J  

$ awk 'FNR==NR{a[FNR]=$2;next} FNR in a' file2 file1
A   23  8   T
A   63  9   9
B   45  3   J

awkどちらの例も期待どおりに機能することがわかります。まず、レコード値に影響を与える現在のレコードのフィールドに新しい値を割り当て、awk新しい値を印刷します。 2番目は、のすべてのawkレコードが処理され、file2スキップされたレコードがないことを示しています。

awk最初のソリューションで最初の行をスキップするのはなぜですか?

私はそれを使用しgawk 4.0.1てテストしましたmawk 1.3.3

答え1

あなたは:

$NF=a[FNR]

最終条件(印刷するかどうかを決定する条件)です。 Assignmentは割り当てられた値を返します(この場合)a[FNR]。質問をリンクするデータファイルの最初の行は次のとおりです。

A   0

a[FNR]に初期化されます$2。これはa[FNR]、isの値0がawkの偽の値であることを意味します。これは、割り当てがfalseであることを意味し、これは条件をfalseにし、デフォルトの印刷動作を抑制します。データファイルを次のように変更した場合:

A   1
A   6   
B   0

これにより、最初の行は印刷されますが、最後の行は失われます。

したがって、最初の行が欠落しているのではなく、最後のフィールドが0(または空白)の行です。まさに最初の行で、最初の行だけです。

答え2

少し調査の最後に答えを見つけました。

まず、これ:

Expression Patterns

An expression pattern will be evaluated as if it were an expression in a 
Boolean context. If the result is true, the pattern will be considered to 
match, and the associated action (if any) will be executed. If the result is 
false, the action will not be executed.

だから私の場合は、$NF=a[FNR]表現モードと見なされます。文書によると、割り当て結果はtrueまたはとして評価されますfalse

私の例では、割り当て結果が0ブールコンテキストで評価され、falseパターンが不一致と見なされ、何もしません。

@Michael Homerのメモ

The assignment to m returned the value assigned.以下は、inが正しくないことを示す例ですawk

$ awk 'function test() {a=2} BEGIN{print test()}'
<blank line>

$ perl -e 'sub test {$a=2}; print test'
2

awkご覧のとおり、例ではどの割り当てが返されますか?

awk 'n=(m=5);END{print n}' prints 5なぜなら副作用awk、これは割り当てが値を返すわけではありません。

関連情報