awk 数组解释?

Dja*_*sef 2 awk

我是 awk 编程的新手,我正在学习数组的工作原理。我找到了这个代码:

awk 'BEGIN{OFS=FS=","}NR==FNR{a[$1]=$2;next}$3 in a && $3 = a[$3]' filez filex
Run Code Online (Sandbox Code Playgroud)

他们将$1作为索引放入数组并$2作为值然后如果$3等于一个索引并且为这个$3 = a[$3]。我不明白这是什么意思,因为第一个文件只有 2 列——与第二个文件$3相比,他们是$3从哪里想出的?!?

输入文件filez

111,111
112,114
113,113
Run Code Online (Sandbox Code Playgroud)

输入文件filex

A,bb,111,xxx,nnn
A,cc,112,yyy,nnn
A,dd,113,zzz,ppp
Run Code Online (Sandbox Code Playgroud)

fra*_*san 6

此脚本的目的是将第二个文件 ( filex)的第三列中的值替换为存储在第一个文件 ( filez)的第二列中的相应值。

NR是当前行相对于第一个处理文件的第一行的编号。它是一个“全局”行计数器。FNR是当前行相对于当前处理文件的开头的行号。
NR==FNR是仅对第一个文件评估为真的条件。相应的操作 ( {a[$1]=$2;next}) 将整个第一个文件逐行放入a字典中,这是一个关联数组,其目的是根据第一列中的相应值查找第一个文件第二列的值。next使awk跳过剩余的条件并重新开始一个循环,阅读下一行。

$3 in a && $3 = a[$3]是具有潜在副作用的条件(分配给$3)。它仅针对第二个文件进行评估(whenNR==FNR为假;请记住,whenNR==FNR为真,$3 in a && $3 = a[$3]被跳过)。对于每一行,如果在a字典中找到第三个字段的值(作为索引),则将其替换为字典中的相应值。然后,如果$3 = a[$3]评估为真,则打印该行(因为在 AWK 程序中,基本上由条件(或“模式”)-动作对组成,条件或动作都可以省略,省略的动作相当于print)。

假设这缩短了filez

111,111
112,114
Run Code Online (Sandbox Code Playgroud)

filex

A,bb,111,xxx,nnn
A,cc,112,yyy,nnn
Run Code Online (Sandbox Code Playgroud)

逐步发生的是:

  1. filez读取第一行;NR==FNR评估为1==1,真;因此,{a[$1]=$2;next}被执行;a[111]设置为111next意味着$3 in a && $3 = a[$3]该行跳过脚本的其余部分 ( )(具体来说,$3现在不使用);不打印任何内容,因为执行的操作不包含任何打印命令;

  2. filez读取第二行和最后一行;NR==FNR评估为2==2,真;{a[$1]=$2;next}被执行;a[112]设置为114$3 in a && $3 = a[$3]再次被跳过,因为next; 同样,没有打印任何内容;

  3. filex读取第一行;NR==FNR评估为3==1,假;因而{a[$1]=$2;next}执行; 评估下一个条件:$3111并且是 的索引值a,因此$3 in a为真并被$3 = a[$3]评估;它导致 的分配a[111],即111$3;由于111不是0也不是空字符串,条件赋值也评估为真并打印当前行;

    A,bb,111,xxx,nnn
    
    Run Code Online (Sandbox Code Playgroud)
  4. filex读取第二行和最后一行;NR==FNR评估为4==2,假;因而{a[$1]=$2;next}执行; 评估下一个条件:$3112并且是 的索引值a,因此$3 in a为真并被$3 = a[$3]评估;它导致 的分配a[112],即114$3;由于114不是0也不是空字符串,条件赋值也评估为真,并打印当前行。

    A,cc,114,yyy,nnn
    
    Run Code Online (Sandbox Code Playgroud)

  • @DjabriJosef 可能。但请注意:1)`$3 in a {$3=a[$3]}` 和 `$3 in a && $3=a[$3]` 不等价:第一个还需要显式的 `print` 来打印该行。并且 `$3=a[$3]` 在前一个表达式中不用作 _condition_(即它不决定是否打印该行),而在后者中。2) 在 AWK 中,_same_ 表达式集(包括赋值)可以在_both_ 模式(我称之为“条件”)和动作中使用。根据设计,不要求模式不改变环境。 (2认同)