快速awkscript如下:
awk ' BEGIN{
split("A\nB\nC\nD", fooarray)
i=0
for (i in fooarray) print fooarray[i]
} '
输出:
D
A
B
C
我觉得我错过了一些重要的细节,但是D在最后的位置怎么样?如在
A
B
C
D
答案 0 :(得分:1)
awk不保证在使用in
时您将遍历数组的顺序。
如果您想确保订单,您可以手动遍历数组(使用split)
的返回值以数字方式行走。
或者,对于awk 4+的版本(我相信),您可以将PROCINFO["sorted_in"]
设置为适当的值。有关详细信息,请参阅GNU Awk User’s Guide。
答案 1 :(得分:1)
D IS位于最后一个位置,您只是不按其索引的连续数字顺序访问数组。看:
awk 'BEGIN{
split("A\nB\nC\nD", fooarray)
for (i in fooarray) print fooarray[i]
print "-------"
for (i=1; i in fooarray; i++) print fooarray[i]
}'
D
A
B
C
-------
A
B
C
D
我觉得这个话题引起了很多混乱,所以让我们看看我是否可以澄清它:
awk数组的两个基本特性是:
因此,假设您有一个像"A B C"
这样的字符串要调用split()
来存储在数组中。当你做split("A B C", arr)
时,你会在记忆中得到这样的东西:
arr[ "3:C" "1:A" "2:B" ]
即。值A,B和C被散列到一些存储器位置并存储在那里以及索引的值,该索引指示它们在原始字符串中出现的顺序。散列算法可以按任何顺序将它们放入内存中。 Google"哈希表"。所以数组实际上存储为这个哈希表:
arr content @ address 1 = "index=3, value=C"
arr content @ address 2 = "index=1, value=A"
arr content @ address 3 = "index=2, value=B"
效率的in
运算符(否则为什么要使用哈希表)只是按照它们存储在内存中的顺序访问数组的元素,所以当你这样做时
for (i in arr)
您将按照它们存储在哈希表中的顺序获取arr
的内容:
address=1 => i = 3, arr[i] = C
++address => i = 1, arr[i] = A
++address => i = 2, arr[i] = B
将i
设置为3然后设置为1然后设置为2,因此arr [i]的值为C,然后是A,然后是B.请注意简单有效的算术++address
来遍历{{}的内容1}}。
如果另一方面你写道:
arr
然后awk将for (i=1; i in arr; i++)
设置为i
然后必须对数组进行哈希查找以搜索具有索引1
的元素并打印出来以便得到:< / p>
1
看到效率的差异?现在我们不再简单地逐步遍历内存地址,我们正在为每个所需的索引进行哈希查找。
在条件上下文中编写i=1
search arr for address containing index i=1
=> address = 2, i = 1, arr[1] = A
++i
search arr for address containing index i=2
=> address = 3, i = 2, arr[2] = B
++i
search arr for address containing index i=3
=> address = 1, i = 3, arr[3] = C
时,例如i in arr
或if (i in arr)
而不是循环范围上下文for (i=1; i in arr; i++)
那么你要求awk做的就是for (i in arr)
的哈希查找,看它是否存在于数组中:< / p>
i
如果您有一个使用字符串索引手动填充的数组,如:
search arr for address containing index i
return 1 if found, 0 otherwise.
并假设散列算法根据其值的长度创建数组内容然后你得到:
arr["First"] = "Bill"
arr["Last"] = "Smith"
arr["Title"] = "Mr."
并且上面描述的所有内容都将以完全相同的方式工作,因此第一个示例使用数字化索引1,2和3的事实与awk中的数组工作方式完全无关 - 所有索引都是字符串并且数组内容存储为arr[ "Title:Mr." "First:Bill" "Last:Smith" ]
对的哈希表。
在GNU awk中,您可以更改index + value
运算符的行为,以便根据各种条件查找数组内容,而不是通过填充in
来简单地遍历地址 - 您可以将其设置为示例到特定的预定义字符串,告诉PROCINFO["sorted_in"]
根据索引的数字或字符串顺序,升序或降序或各种其他标准查找数组内容,您可以编写自己的函数来控制顺序。如果您需要特定的数组遍历顺序,这对于改善代码的简洁性非常有用,但如果您使用它并且不需要它,则显然会带来性能损失。有关详细信息,请参阅http://www.gnu.org/software/gawk/manual/gawk.html#Controlling-Array-Traversal。
希望这有助于解释awk数组存储和in
运算符的工作方式。如果没有 - 抱歉引起混乱!