web-dev-qa-db-fra.com

Comment puis-je obtenir la longueur d'un tableau dans awk?

Cette commande

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

ne fonctionne pas pour moi et donne ce message d'erreur

awk: ligne 1: référence illégale à un tableau

Pourquoi?

45
softghost

Lorsque vous divisez un tableau, le nombre d'éléments est renvoyé. Vous pouvez donc dire:

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

La sortie est:

2
76
shellter

La fonction de M. Ventimiglia nécessite un petit ajustement pour effectuer le travail (voir le point-virgule pour une déclaration):

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

Mais ne travaillez pas tous les cas ou les temps. En effet, la manière dont awk stocke et "voit" les index des tableaux: ils sont associatifs et non nécessairement contigus (comme C.) Donc, i ne renvoie pas le "dernier" élément.

Pour le résoudre, vous devez compter:

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

Et, de cette manière, prenez garde aux autres types d'index de tableaux "unidimensionnels", où l'index peut être une chaîne. Veuillez consulter: http://docstore.mik.ua/orelly/unix/sedawk/ch08_04.htm . Pour les tableaux "multidimensionnels" et arbitraires, voir http://www.gnu.org/software/gawk/manual/html_node/Walking-Arrays.html#Walking-Arrays .

35
0zkr PM

Je ne pense pas que la personne demande: "Comment scinder une chaîne et obtenir la longueur du tableau résultant?" Je pense que la commande qu'ils fournissent n'est qu'un exemple de la situation dans laquelle elle s'est produite. En particulier, je pense que la personne demande 1) Pourquoi length(array) provoque-t-il une erreur et 2) Comment obtenir la longueur d'un tableau dans awk?

La réponse à la première question est que la fonction length ne fonctionne pas sur les tableaux dans un awk standard POSIX, mais dans GNU awk (gawk) et quelques autres variantes. La réponse à la deuxième question est (si nous voulons une solution qui fonctionne dans toutes les variantes de awk) de faire un balayage linéaire. 

Par exemple, une fonction comme celle-ci

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

NOTE: le deuxième paramètre i mérite une explication.

La manière dont vous introduisez les variables locales dans awk est en tant que paramètre de fonction supplémentaire et la convention est de l'indiquer en ajoutant des espaces supplémentaires avant ces paramètres. Ceci est discuté dans le manuel de GNU Awk .

21

Je veux juste souligner que:

  • Il n'est pas nécessaire de stocker le résultat de la fonction split pour l'imprimer.
  • Si aucun séparateur n'est fourni pour le fractionnement, la valeur par défaut FS (espace vide) sera utilisée. 
  • La partie END est inutile ici.

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

Dans gawk, vous pouvez utiliser la fonction 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

Depuis Le guide de l'utilisateur GNU Awk :

Avec gawk et plusieurs autres implémentations d'awk, lorsqu'un argument de tableau est attribué, la fonction length() renvoie le nombre d'éléments contenus dans le. tableau. (c.e.) Ceci est moins utile que cela puisse paraître au premier abord, comme il n'est pas garanti que le tableau soit indexé de un au nombre de éléments en elle. Si --lint est fourni sur la ligne de commande (voir Options), gawk avertit que le passage d'un argument de tableau n'est pas portable . Si --posix est fourni, l'utilisation d'un argument de tableau est une erreur fatale (voir Tableaux).

8
fedorqui

exemple sur MacOSX Lion pour afficher les ports utilisés (la sortie peut être 192.168.111.130.49704 ou :: 1.49704):

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

Dans cet exemple, cela affiche le dernier élément de tableau de la 4ème colonne: "49704"

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

Essayez ceci si vous n'utilisez pas gawk.

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

Sortie:

aaa
3
ccc

8.4.4 Utilisation de split () pour créer des tableaux http://docstore.mik.ua/orelly/unix/sedawk/ch08_04.htm

0
Weichao Liu