~からこの問題、私は次の解決策で答えた。
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
awk
whenが最初の行を印刷しないため、機能しません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
、これは割り当てが値を返すわけではありません。