Bea*_*ode 25 arrays awk initialization
是否可以在AWK中初始化这样的数组?
Colors[1] = ("Red", "Green", "Blue")
Colors[2] = ("Yellow", "Cyan", "Purple")
Run Code Online (Sandbox Code Playgroud)
然后有一个二维数组,其中Colors [2,3] ="Purple".
从另一个线程我明白这是不可能的("遗憾的是,没有办法在不滥用split()的情况下一次设置一个数组").无论如何,我想100%肯定,我确信还有其他人有同样的问题.
我正在寻找最简单的方法来初始化像上面那样的数组,将它编写得很好.
Jon*_*ler 13
您可以轻松地创建二维数组.你不能做的,AFAIK,是在一次操作中初始化它.正如dmckee在注释中暗示的那样,无法初始化数组的原因之一是对下标的类型没有限制,因此不要求它们是纯数字.您可以在下面的脚本中执行多项任务.下标由变量SUBSEP指定的模糊字符正式分隔,默认值为034(U + 001C,FILE SEPARATOR).显然,如果其中一个索引包含此字符,则会出现混淆(但是最后一次在字符串中使用该字符是什么时候?).
BEGIN {
Colours[1,1] = "Red"
Colours[1,2] = "Green"
Colours[1,3] = "Blue"
Colours[2,1] = "Yellow"
Colours[2,2] = "Cyan"
Colours[2,3] = "Purple"
}
END {
for (i = 1; i <= 2; i++)
for (j = 1; j <= 3; j++)
printf "Colours[%d,%d] = %s\n", i, j, Colours[i,j];
}
Run Code Online (Sandbox Code Playgroud)
示例运行:
$ awk -f so14063783.awk /dev/null
Colours[1,1] = Red
Colours[1,2] = Green
Colours[1,3] = Blue
Colours[2,1] = Yellow
Colours[2,2] = Cyan
Colours[2,3] = Purple
$
Run Code Online (Sandbox Code Playgroud)
Bea*_*ode 12
谢谢你的回答.无论如何,对于那些想要初始化一维数组的人来说,这是一个例子:
SColors = "Red_Green_Blue"
split(SColors, Colors, "_")
print Colors[1] " - " Colors[2] " - " Colors[3]
Run Code Online (Sandbox Code Playgroud)
Ste*_*eve 10
如果有GNU awk
,则可以使用真正的多维数组.虽然这个答案使用了这个split()
功能,但它肯定不会滥用它.运行如下:
awk -f script.awk
Run Code Online (Sandbox Code Playgroud)
内容script.awk
:
BEGIN {
x=SUBSEP
a="Red" x "Green" x "Blue"
b="Yellow" x "Cyan" x "Purple"
Colors[1][0] = ""
Colors[2][0] = ""
split(a, Colors[1], x)
split(b, Colors[2], x)
print Colors[2][3]
}
Run Code Online (Sandbox Code Playgroud)
结果:
Purple
Run Code Online (Sandbox Code Playgroud)
现有的答案很有帮助,并且涵盖了所有方面,但我想我应该给出更有针对性的总结。
这个问题混淆了两个方面:
Awk 没有数组文字(初始化程序)语法。
最简单的解决方法是:
split()
函数将该字符串拆分为数组的元素。$ awk 'BEGIN { n=split("Red Green Blue", arr); for (i=1;i<=n;++i) print arr[i] }'
Red
Green
Blue
Run Code Online (Sandbox Code Playgroud)
这就是OP在他们自己的有用答案中所做的。
如果元素本身包含空格,请使用不属于数据的自定义分隔符,|
在此示例中:
$ awk 'BEGIN { n=split("Red (1)|Green (2)", arr, "|"); for (i=1;i<=n;++i) print arr[i] }'
Red (1)
Green (2)
Run Code Online (Sandbox Code Playgroud)
根据 POSIX,Awk没有真正的多维数组,只是使用一维数组对其进行模拟,该数组的索引与内置变量的值隐式连接SUBSEP
以形成单个键(索引;请注意,所有Awk 数组都是联想)。
arr[1, 2]
实际上与 相同arr[1 SUBSEP 2]
,其中1 SUBSEP 2
是构建键值的字符串连接。for (i in ...)
,例如仅获取主(伪)维度的所有子索引1
。SUBSEP
,这是一个很少使用的控制字符,不太可能出现在日期中;在 ASCII 和 UTF-8 中,它表示为单字节;如果需要,您可以更改该值。0x1f
相比之下,GNU Awk作为一个非标准扩展,确实支持真正的多维数组。
arr[1,2]
您必须使用arr[1][2]
.POSIX 兼容示例(类似于TrueY 的有用答案):
awk 'BEGIN {
n=split("Red Green Blue", arrAux); for (i in arrAux) Colors[1,i] = arrAux[i]
n=split("Yellow Cyan Purple", arrAux); for (i in arrAux) Colors[2,i] = arrAux[i]
print Colors[1,2]
print "---"
# Enumerate all [2,*] values - see comments below.
for (i in Colors) { if (index(i, 2 SUBSEP)==1) print Colors[i] }
}'
Green
---
Yellow
Cyan
Purple
Run Code Online (Sandbox Code Playgroud)
请注意,使用复合键用一维数组模拟多维数组具有以下不方便的含义:
auxArr
需要辅助数组,因为您无法直接填充数组的给定(伪)维度。
您不能使用 枚举仅一个(伪)维度for (i in ...)
,只能枚举跨(伪)维度的所有索引。
for (i in Colors) { if (index(i, 2 SUBSEP)==1) print Colors[i] }
上面展示了如何通过枚举所有键,然后仅匹配第一个组成索引为 的键来解决此2
问题,这意味着键值必须以 开头2
,后跟SUBSEP
。GNU Awk 示例(类似于Steve 的有用答案,并根据Ed Morton 的评论进行了改进):
GNU Awk 对真正的多维数组的(非标准)支持使得 POSIX 兼容解决方案的不便(大部分)消失了
(但是,GNU Awk 也没有数组初始值设定项):
gawk 'BEGIN {
Colors[1][""]; split("Red Green Blue", Colors[1])
Colors[2][""]; split("Yellow Cyan Purple", Colors[2])
# NOTE: Always use *separate* indices: [1][2] instead of [1,2]
print Colors[1][2]
print "---"
# Enumerate all [2][*] values
for (i in Colors[2]) print Colors[2][i]
}'
Run Code Online (Sandbox Code Playgroud)
笔记:
重要提示:如上所述,要寻址多维数组中的特定元素,请始终使用单独的索引;例如,[1][2]
而不是[1,2]
。
[1,2]
您将获得标准 POSIX 规定的行为,并且您将错误地创建一个带有(字符串连接)值的新的单个索引(键)1 SUBSEP 2
。split()
可以方便地用于直接填充子数组。
然而,作为先决条件,必须初始化二维目标数组:
Colors[1][""]
就Colors[2][""]
这样做。[""]
只是用来创建一个二维数组;split()
当稍后填充该维度时,它会被丢弃。for (i in ...)
支持枚举特定维度:
for (i in Colors[2]) ...
方便地仅枚举 的子索引Colors[2]
。 归档时间: |
|
查看次数: |
44155 次 |
最近记录: |