Прогулка по многомерным массивам в Mawk

Прогулка по многомерным массивам в Mawk

Я могу сделать это правильно в gawk, но когда я попытался опубликовать свой код на машине, где он будет работать, я понял, что он использует mawk...

$ cat multidim.gawk
# test of multidimensional arrays
// {
        A[1][1]="A11"
        A[1][2]="A12"
        A[2][1]="A21"
        A[2][2]="A22"

        i=2
        for ( j in A[i] )
        {
                print "i=" i " j=" j " A[i][j]=" A[i][j]
        }
}


$ echo hi | awk -f multidim.gawk
i=2 j=1 A[i][j]=A21
i=2 j=2 A[i][j]=A22

похоже, у mawk другое представление о том, как должны работать многомерные массивы. Когда я запускаю его на Debian с mawk, я получаю синтаксическую ошибку. A[i,j] кажется правильным синтаксисом, и он «синтезирует» многомерные массивы.

Итак, я попробовал две вещи, но ни одна не сработала:

$ cat multidim.mawk
// {
        A[1,1]="A11"
        A[1,2]="A12"
        A[2,1]="A21"
        A[2,2]="A22"

        i=2
        for ( j in A[i] )
        {
                print "i=" i " j=" j "a[i,j]=" a[i,j]
        }
}

$ echo hi | awk -f multidim.mawk 
awk: multidim.mawk: line 9: syntax error at or near [

Кажется разумным, использование индекса массива 1dim для «многомерного» массива приводит к ошибке.

Пытаюсь просто обойти ВЕСЬ массив, чтобы можно было использовать оператор if для выбора даже первого измерения (крайне неэффективно и ужасно)... но я даже этого не могу сделать!:

$ cat multidim2.mawk
# test of multidimensional arrays
// { 
    A[1,1]="A11"    
    A[1,2]="A12"    
    A[2,1]="A21"    
    A[2,2]="A22"    

    for ( (i, j) in A )
    {
        print "i=" i " j=" j "a[i,j]=" a[i,j]
    }
}
$ echo hi | awk -f multidim2.mawk 
awk: multidim2.mawk: line 8: syntax error at or near )

Есть ли способ обойти многомерный массив в Mawk?

Есть ли справочник по языку, кроме man-страницы mawk?

Спасибо!

решение1

mawknawk) предоставить толькосинтезированные многомерные массивы.

gawkобеспечивает (с версии 4.0, спасибо)manatwork) настоящие многомерные массивы, хотя страница руководства (IMHO) немного сбивает с толку: сразу после введения if ((i,j) in array)следует "Конструкцию in также можно использовать в цикле for для перебора всех элементов массива." (исправлено с версии 4.1.1!).

Но for ((i,j) in array)это не способ перебрать их, а gawkспособ такой (который вы использовали изначально):

 for (i in array)
     for (j in array[i])
         print array[i][j]

С nawk/ mawkвы застряли ссинтезированные многомерные массивы, так

for (ij in A) {
    split(ij,xx,SUBSEP);
    printf("A[%s,%s]=%s\n",xx[1],xx[2],A[ij])
}

Теперь вашей следующей проблемой будетзаказ, индексы массива неявно являются строковым типом, а массивы неявно неупорядочены. Если только у вас нет отдельного знания индексов, как это было бы в случае с простым неразреженным массивом с последовательными целочисленными индексами от 0 до N. gawkпредлагаетрешение для упорядоченногоin.

Если вы знаете индексы синтезированного массива, то вы можете использовать A[i,j](который рассматривается как A[i SUBSEP j]), или for/ inи некоторое разбиение строки для перестроения списка iи j, или if ((i,j) in A)(проверка на наличие, безавтовивификацияиндексов).

В gawkвы не можете использовать (i,j) in arr, где arr является настоящим многомерным массивом, вам нужно разбить его на два (или сколько угодно измерений) forцикла, как указано выше. Однако для полной корректности внутренние циклы должны содержать условие isarray(), поскольку не требуется, чтобы каждый элемент в arr[i]свою очередь был массивом, gawk с радостью допускает и скаляры.

Я не знаю никакой mawkконкретной документации, кроместраница руководства, он стремится стать стандартной новой awk(т.е. nawk) реализацией (поэтому нет настоящих многомерных массивов, нет сортировки индексов и нет isarray()).

Связанный контент