Подтвердить что ты не робот

Как я могу получить длину массива в awk?

Эта команда

echo "hello world" | awk '{split($0, array, " ")} END{print length(array) }'

не работает для меня и дает это сообщение об ошибке

awk: строка 1: незаконная ссылка на массив массивов

Почему?

4b9b3361

Ответ 1

Когда вы разбиваете массив, возвращается количество элементов, поэтому вы можете сказать:

echo "hello world" | awk '{n=split($0, array, " ")} END{print n }'
# ------------------------^^^--------------------------------^^

Выход:

2

Ответ 2

Функция Mr. Ventimiglia требует небольшой корректировки для выполнения работы (см. Точку с запятой для утверждения):

function alen(a, i) {
    for(i in a);
    return i
}

Но не работают все случаи или времена. Это потому, что способ, которым awk хранит и "видит" индексы массивов: они ассоциативны и не обязательно являются смежными (например, C.) Итак, i не возвращаю "последний" элемент.

Чтобы решить это, вам нужно посчитать:

function alen(a, i, k) {
    k = 0
    for(i in a) k++
    return k
}

И, таким образом, позаботьтесь о других типах индексов "одномерных" массивов, где индекс может быть строкой. Пожалуйста, смотрите: http://docstore.mik.ua/orelly/unix/sedawk/ch08_04.htm. Для "многомерных" и произвольных массивов см. Http://www.gnu.org/software/gawk/manual/html_node/Walking-Arrays.html#Walking-Arrays.

Ответ 3

Я не думаю, что человек спрашивает: "Как мне разбить строку и получить длину полученного массива?" Я думаю, что команда, которую они предоставляют, является лишь примером ситуации, когда она возникла. В частности, я думаю, что человек спрашивает: 1) Почему длина (массив) вызывает ошибку, и 2) Как я могу получить длину массива в awk?

Ответ на первый вопрос заключается в том, что функция длины не работает с массивами в стандартном awk POSIX, хотя она работает в GNU awk (gawk) и некоторых других вариантах. Ответ на второй вопрос (если мы хотим, чтобы решение работало во всех вариациях awk) выполняло линейное сканирование.

Например, такая функция:

function alen (a,     i) {
    for (i in a);
    return i;}

ПРИМЕЧАНИЕ. Второй параметр я требует пояснения.

Способ, которым вы вводите локальные переменные в awk, - это дополнительные параметры функции, и условием является указание этого путем добавления дополнительных пробелов перед этими параметрами. Это обсуждается в руководстве GNU Awk здесь.

Ответ 4

Просто хочу указать, что:

  • Не нужно сохранять результат функции split, чтобы распечатать его.
  • Если разделитель не поставляется для разделения, будет использоваться значение по умолчанию FS (пустое пространство).
  • Часть END здесь бесполезна.

    echo 'hello world' | awk '{print split($0, a)}'
    

Ответ 5

В gawk вы можете использовать функцию length():

$ gawk 'BEGIN{a[1]=1; a[2]=2; a[23]=45; print length(a)}'
3

$ gawk 'BEGIN{a[1]=1; a[2]=2; print length(a); a[23]=45; print length(a)}'
2
3

Из руководства пользователя GNU Awk:

В gawk и нескольких других реализациях awk, когда передается аргумент массива, функция length() возвращает количество элементов в массиве. (ce) Это менее полезно, чем может показаться на первый взгляд, поскольку не гарантируется, что массив будет проиндексирован от одного до количества элементов в нем. Если в командной строке указано --lint (см. Параметры), gawk предупреждает, что передача аргумента массива не переносима. Если задано --posix, использование аргумента массива является фатальной ошибкой (см. Массивы).

Ответ 6

на MacOSX Lion, чтобы показать используемые порты (вывод может быть 192.168.111.130.49704 или:: 1.49704):

   netstat -a -n -p tcp | awk '/\.[0-9]+ / {n=split($4,a,"."); print a[n]}'

В этом примере, который печатает последний элемент массива 4-го столбца: "49704"

Ответ 7

echo "hello world" | awk '{lng=split($0, array, " ")} END{print lng) }'

Ответ 8

Попробуйте это, если вы не используете gawk.

awk 'BEGIN{test="aaa bbb ccc";a=split(test, ff, " "); print ff[1]; print a; print ff[a]}'

Вывод:

aaa
3
ccc

8.4.4 Использование split() для создания массивов http://docstore.mik.ua/orelly/unix/sedawk/ch08_04.htm