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?
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
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 .
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 .
Je veux juste souligner que:
split
pour l'imprimer.FS
(espace vide) sera utilisée. La partie END
est inutile ici.
echo 'hello world' | awk '{print split($0, a)}'
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).
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"
echo "hello world" | awk '{lng=split($0, array, " ")} END{print lng) }'
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