如果你看看这个awk测试的输出,你会看到arrayin awk似乎是以某种随机模式打印出来的.对于相同数量的输入,它似乎是相同的顺序.它为什么这样做?
echo "one two three four five six" | awk '{for (i=1;i<=NF;i++) a[i]=$i} END {for (j in a) print j,a[j]}'
4 four
5 five
6 six
1 one
2 two
3 three
Run Code Online (Sandbox Code Playgroud)
echo "P04637 1A1U 1AIE 1C26 1DT7 1GZH 1H26 1HS5 1JSP 1KZY 1MA3 1OLG 1OLH 1PES 1PET 1SAE 1SAF 1SAK 1SAL 1TSR 1TUP 1UOL 1XQH 1YC5 1YCQ" | awk '{for (i=1;i<=NF;i++) a[i]=$i} END {for (j in a) print j,a[j]}'
17 1SAF
4 1C26
18 1SAK
5 1DT7
19 1SAL
6 1GZH
7 1H26
8 1HS5
9 1JSP
10 1KZY
20 1TSR
11 1MA3
21 1TUP
12 1OLG
22 1UOL
13 1OLH
23 1XQH
14 1PES
1 P04637
24 1YC5
15 1PET
2 1A1U
25 1YCQ
16 1SAE
3 1AIE
Run Code Online (Sandbox Code Playgroud)
为什么会这样做,这有什么规则吗?
从8.在awk中的数组 - > 8.5在参考for (value in array)语法时,在GNU Awk用户指南中扫描数组的所有元素:
此语句访问数组元素的顺序由awk中数组元素的内部排列决定,无法控制或更改.如果通过循环体中的语句将新元素添加到数组中,则会导致问题; 无法预测for循环是否会达到它们.同样,在循环中更改var可能会产生奇怪的结果.最好避免这样的事情.
因此,如果要按照存储顺序打印数组,则必须使用经典for循环:
for (j=1; j<=NF; j++) print j,a[j]
Run Code Online (Sandbox Code Playgroud)
$ awk '{for (i=1;i<=NF;i++) a[i]=$i} END {for (j=1; j<=NF; j++) print j,a[j]}' <<< "P04637 1A1U 1AIE 1C26 1DT7 1GZH 1H26 1HS5 1JSP 1KZY 1MA3 1OLG 1OLH 1PES 1PET 1SAE 1SAF 1SAK 1SAL 1TSR 1TUP 1UOL 1XQH 1YC5 1YCQ"
1 P04637
2 1A1U
3 1AIE
4 1C26
5 1DT7
6 1GZH
7 1H26
8 1HS5
9 1JSP
10 1KZY
11 1MA3
12 1OLG
13 1OLH
14 1PES
15 1PET
16 1SAE
17 1SAF
18 1SAK
19 1SAL
20 1TSR
21 1TUP
22 1UOL
23 1XQH
24 1YC5
25 1YCQ
Run Code Online (Sandbox Code Playgroud)
Awk使用哈希表来实现关联数组.这只是这种特定数据结构的固有属性.特定元素存储到数组中的位置取决于值的哈希值.要考虑的其他因素是哈希表的实现.如果它具有内存效率,它将使用模数函数或其他方法限制每个键存储的范围.您还可能会因为不同的键而产生冲突哈希值,因此会发生链接,这会再次影响顺序,具体取决于首先插入的键.
(key in array)当适当地使用循环遍历每个键时,构造完全正常,但是你不能指望顺序,你不应该array在循环中更新,因为你可能会array[key]错误地多次处理.
Think Complexity一书中有很好的哈希表描述.