
Я могу сделать это правильно в 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
mawk
(и nawk
) предоставить толькосинтезированные многомерные массивы.
gawk
обеспечивает (с версии 4.0, спасибо)manatwork) настоящие многомерные массивы, хотя страница руководства (IMHO) немного сбивает с толку: сразу после введения (исправлено с версии 4.1.1!).if ((i,j) in array)
следует "Конструкцию in также можно использовать в цикле for для перебора всех элементов массива."
Но 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()
).