【问题标题】:Array assignment in awk on ksh environmentksh 环境中 awk 中的数组分配
【发布时间】:2020-04-28 22:02:22
【问题描述】:

我的一个 awk 脚本在 bash shell 环境中运行良好,但我发现它不适用于 ksh (AIX)。

awk: Cannot make an assignment to j. It is an array name.

我不擅长 awk 脚本,向我展示错误的部分会很有帮助,这样我就可以在 ksh 上运行它而不会出现任何问题。 我还想知道是否可以在 awk 脚本的开头定义 shell 类型,例如 bash、ksh 和 csh。有什么办法吗?

输入和完整的 awk 脚本

Job ID    : 56
Status    : Done - 1 object completed

ID     Tablename                               Status         Time         Total Rows %Comp Total Time  
------ --------------------------------------- -------------- ------------ ---------- ----- ------------
1      "TEST"."TEST"."TEST"                    In Good                 N/A    1708219   100         1:26


BEGIN {
    count = 0
    job_id = 0
    status = 0
    PROCINFO["sorted_in"] = "@ind_num_asc"
}

/^Job ID/ {
    job_id = $4 
    a[job_id] = job_id "#-1#no_data#no_data#no_data#-1#-1#no_data"
    count++
}

/^Status/ {
   match($0,/[0-9]+/)
   status = substr($0, RSTART, RLENGTH)
   temp = a[job_id]
   delete a[job_id]
   a[job_id] = temp "#" status
}

/^[0-9]/ {
    delete a[job_id]
    string = job_id
    step_skip = 0
    for (i=1; i <= NF; i++) {
        if (i == 4 || (i == 5 && step_skip == 1)) {
            continue
        } else if (i == 2) {
            gsub(/"/, "", $i);
            gsub(/\./, "#", $i);
            string = string "#" $i
        } else if (i == 3){
            if (match($i, /^Out/)) {
                string = string "#" $i " " $(i+1)
                step_skip = 1
           } else if (match($i, /^In/)) {
                string = string "#" $i " " $(i+1)
                step_skip = 1
            } else if (match($i, /^Skipped/)) {
                string = string "#" $i "#-1#-1#no_data"
                break
            } else {
                string = string "#" $i
            }
        } else if (i == 6 || (i == 7 && step_skip == 1)) {
            if (match($i, /:/)) {
                string = string "#-1#" $i 
            } else {
                string = string "#" $i
            }
        }else {
            string = string "#" $i
        }
    }
    a[job_id, $1] = string "#" status

}

END {

    for (j in a) {
        if (j in a) {
            print a[j]
        }

        temp = a[j]

        if (PROCINFO["temp"] == "array") {
            for (k in j) {
                print a[j, k]
            }
        }


    }

}

【问题讨论】:

  • 您确定是您共享的代码导致了错误吗?它不会尝试分配给 j,因此似乎不太可能。如果删除END 块,错误会消失吗?
  • awk 与您的 shell 无关,反之亦然。发布一个最小的、完整的 awk 脚本来演示该问题,以便我们帮助您调试它。
  • @EdMorton 感谢您的评论。粘贴了完整的脚本。
  • for (k in j) { 似乎是错误的,您将j 视为一个数组,而事实并非如此。
  • 您没有接受@EdMorton 的回答。你能解释一下你不清楚的地方吗?

标签: awk ksh


【解决方案1】:

awk 与您的 shell 无关,反之亦然。您遇到问题是由于在运行不同版本的 awk 时暴露了代码中的错误,而不是从不同版本的 shell 调用 awk。

在某些 awk 中,例如 Mac OS 上的默认 BSD awk for (k in j) 存在于代码中,即使在您的情况下无法达到的腿中,也足以让 awk 将 j 识别为一个数组,因为您在其上使用了数组操作 in,所以当 awk 遇到您将 j 视为代码中其他地方的标量 (for (j in a)) 时,awk 告诉您不能这样做,因为 j是一个数组。

您的代码中还有其他问题,例如,当您没有运行 gawk 并且您将伪多维数组索引语法 (a[i,j]) 与针对只能使用 gawks arrays-of-arrays 语法 (a[i][j]) 创建的数组,并执行诸如 for (j in a) { if (j in a) { 之类的操作,其中 if 不可能失败,还有 temp = a[j]; if (PROCINFO["temp"] == "array") 其中 temp 不可能是一个数组,否则分配将失败。如果您需要有关代码的这些或其他方面的帮助,请随时发布新问题。

【讨论】:

  • 很好的解释,有助于解决问题!
猜你喜欢
  • 2011-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-28
  • 2020-04-21
  • 2011-01-29
  • 1970-01-01
相关资源
最近更新 更多