GNU Awk三维数组写入正常但访问返回空值问题求解
问题原因
你的代码存在3个核心逻辑错误,导致多维数组下标计算完全错位:
- 用
for (i in rows)遍历数组时,awk关联数组的遍历顺序不保证和存入时的数字下标顺序一致,基于无序遍历结果计算行号、板号的逻辑不可靠。 - 板号
b的递增逻辑错误:当前代码每处理1行只要满足i%5==0就将b加1,处理第1行(i=0)后b就会变为1,属于第0块的剩余4行数据会被写入其他板号下,boards[0]中仅存1行数据,自然无法访问到boards[0][1][1]对应的值。 split(rows[i], nums, " ")以单个空格作为分隔符时,行首前导空格、数字间的多个连续空格会拆分出空字符串元素,导致列号计算错位。
你看到调试打印能正常输出值,是因为打印操作发生在赋值的同一时刻,不管下标计算是否符合预期,刚写入的值当下读取肯定是正常的,但数据实际被存到了错误的下标位置。
修复方案
按以下逻辑调整代码即可:
- 遍历
rows数组时按下标顺序遍历,不要用无序的for...in语法 - 板号、行号直接通过行下标计算,不要靠遍历过程中动态计数,避免顺序错误
- 分割行内容时不指定分隔符,使用awk默认的空白分割规则,自动忽略前导空格、连续空格,不会产生空元素
修复后的完整代码如下:
BEGIN { row_cnt = 0 } NR == 1 { # 第一行是逗号分隔的抽取数字,按逗号分割 split($0, draws, ",") next } # 跳过所有空行 NF == 0 { next } # 按顺序存储所有宾果板的行 { rows[row_cnt++] = $0 } END { for (i = 0; i < row_cnt; i++) { # 默认按任意连续空白分割,自动处理前后空格、多空格 split(rows[i], nums) b = int(i / 5) # 每5行对应一个板,直接计算板号 r = i % 5 # 计算当前行在板内的行号 for (j = 1; j <= 5; j++) { n = j - 1 # 列号从0开始计数 boards[b][r][n] = nums[j] } } # 测试输出第0个板第1行第1列的值,正确结果为2 print boards[0][1][1] }
运行命令awk -f solve.awk ex.txt即可得到正确输出2。
内容的提问来源于stack exchange,提问作者JiKro
相关产品推荐
相关产品推荐

