Эта команда
echo "hello world" | awk '{split($0, array, " ")} END{print length(array) }'
не работает для меня и дает это сообщение об ошибке
awk: строка 1: незаконная ссылка на массив массивов
Почему?
Эта команда
echo "hello world" | awk '{split($0, array, " ")} END{print length(array) }'
не работает для меня и дает это сообщение об ошибке
awk: строка 1: незаконная ссылка на массив массивов
Почему?
Когда вы разбиваете массив, возвращается количество элементов, поэтому вы можете сказать:
echo "hello world" | awk '{n=split($0, array, " ")} END{print n }'
# ------------------------^^^--------------------------------^^
Выход:
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.
Я не думаю, что человек спрашивает: "Как мне разбить строку и получить длину полученного массива?" Я думаю, что команда, которую они предоставляют, является лишь примером ситуации, когда она возникла. В частности, я думаю, что человек спрашивает: 1) Почему длина (массив) вызывает ошибку, и 2) Как я могу получить длину массива в awk?
Ответ на первый вопрос заключается в том, что функция длины не работает с массивами в стандартном awk POSIX, хотя она работает в GNU awk (gawk) и некоторых других вариантах. Ответ на второй вопрос (если мы хотим, чтобы решение работало во всех вариациях awk) выполняло линейное сканирование.
Например, такая функция:
function alen (a, i) {
for (i in a);
return i;}
ПРИМЕЧАНИЕ. Второй параметр я требует пояснения.
Способ, которым вы вводите локальные переменные в awk, - это дополнительные параметры функции, и условием является указание этого путем добавления дополнительных пробелов перед этими параметрами. Это обсуждается в руководстве GNU Awk здесь.
Просто хочу указать, что:
split
, чтобы распечатать его.FS
(пустое пространство).Часть END
здесь бесполезна.
echo 'hello world' | awk '{print split($0, a)}'
В 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, использование аргумента массива является фатальной ошибкой (см. Массивы).
на 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"
echo "hello world" | awk '{lng=split($0, array, " ")} END{print lng) }'
Попробуйте это, если вы не используете 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