Как я могу получить длину массива в awk? - PullRequest
54 голосов
/ 19 февраля 2012

Эта команда

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

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

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

Почему?

Ответы [ 8 ]

82 голосов
/ 19 февраля 2012

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

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

Вывод:

2
36 голосов
/ 16 октября 2013

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

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.

21 голосов
/ 03 июля 2013

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

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

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

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

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

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

16 голосов
/ 16 июля 2012

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

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

    echo 'hello world' | awk '{print split($0, a)}'
    
11 голосов
/ 09 декабря 2015

В 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() возвращает количество элементов массив . (c.e.) Это менее полезно, чем может показаться на первый взгляд, так как не гарантируется, что массив будет проиндексирован от одного до количества элементы в нем. Если --lint указан в командной строке (см. Опции), gawk предупреждает, что передача аргумента массива не переносима. Если указан параметр --posix, использование аргумента массива является фатальной ошибкой (см. Массивы).

2 голосов
/ 08 июня 2013
Образец

в 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"

0 голосов
/ 08 марта 2017

Попробуйте, если вы не используете 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

0 голосов
/ 19 февраля 2012
echo "hello world" | awk '{lng=split($0, array, " ")} END{print lng) }'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...