Назначение массива в awk в среде k sh - PullRequest
0 голосов
/ 29 апреля 2020

Один из моих сценариев awk хорошо работает в bash оболочке, но я обнаружил, что он не работает в k sh (AIX).

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

Я не очень хорош в сценариях awk и было бы полезно показать мне неправильную часть, чтобы я мог запустить ее на k sh без каких-либо проблем. Мне также интересно, могу ли я определить типы оболочек, такие как bash, k sh и csh в начале скрипта awk. Есть ли способ?

INPUT & Full awk script

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]
            }
        }


    }

}

1 Ответ

2 голосов
/ 29 апреля 2020

awk не имеет ничего общего с вашей оболочкой и наоборот. Вы столкнулись с проблемой из-за ошибки в вашем коде, которая была обнаружена при запуске разных версий awk, не вызывая awk из разных версий оболочки.

В некоторых awk, таких как стандартный BSD awk для Ma c OS for (k in j), присутствующая в коде, даже на участке, который не может быть достигнут, как в вашем случае, достаточно, чтобы awk идентифицировал j как массив, так как вы используете операцию массива in поэтому, когда awk встречает вас, вы рассматриваете j как скаляр в другом месте вашего кода (for (j in a)), awk говорит, что вы не можете этого сделать, потому что j - это массив.

У вас есть другие проблемы в вашем коде, такие как использование конструкций gawk-only, таких как PROCINFO[], когда вы не запускаете gawk и смешиваете синтаксис индексации псевдо-многомерных массивов (a[i,j]) с тестами для массивов, которые могли быть только создается с использованием синтаксиса gawks-массивов-массивов (a[i][j]) и выполняет такие действия, как for (j in a) { if (j in a) {, где if не может быть невозможен, а также temp = a[j]; if (PROCINFO["temp"] == "array"), где temp не может быть массивом o r назначение было бы неудачным. Не стесняйтесь задавать новые вопросы, если вы хотите помочь с теми или иными аспектами вашего кода.

...