formattage awk

Le
Lulu
[xp : fcolc,fcou ; fu2 :fcou ]

[supersedes : erreur dans mon sed]

Yo !

Je suis en train d'écrire un one-liner qui donne le nombre d'octets
envoyés par l'interface réseau :

$ cat /proc/net/dev
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
lo: 40750160 55083 0 0 0 0 0 0 40750160 55083 0 0 0 0 0 0
wlp2s0: 400565197 508500 0 142 0 0 0 0 177714515 445447 0 0 0 0 0 0

$ grep wlp2s0 /proc/net/dev | awk -F ' ' '{print $10}'
178064693

$ grep wlp2s0 /proc/net/dev | awk -F ' ' '{print $10}' | rev | sed -E 's//& /g' | rev
178 065 488

Je passe par rev et sed car je n'ai rien compris au formattage de chaîne avec
awk.

(rev est nécessaire pour que '1234' donne bien '1 234' et non '123 4')


Merci de votre aide.
  • Partager ce contenu :
Vos réponses
Trier par : date / pertinence
Benoit Izac
Le #26541713
Bonjour,
Le 28/03/2020 à 20:44, Lulu a écrit dans le message
Je suis en train d'écrire un one-liner qui donne le nombre d'octets
envoyés par l'interface réseau :
$ cat /proc/net/dev
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
lo: 40750160 55083 0 0 0 0 0 0 40750160 55083 0 0 0 0 0 0
wlp2s0: 400565197 508500 0 142 0 0 0 0 177714515 445447 0 0 0 0 0 0
$ grep wlp2s0 /proc/net/dev | awk -F ' ' '{print $10}'
178064693
$ grep wlp2s0 /proc/net/dev | awk -F ' ' '{print $10}' | rev | sed -E 's/.../& /g' | rev
178 065 488
Je passe par rev et sed car je n'ai rien compris au formattage de chaîne avec
awk.
(rev est nécessaire pour que '1234' donne bien '1 234' et non '123 4')

LC_NUMERIC=fr_FR printf "%'.f" $(awk '/wlp2s0/{print $10}' /proc/net/dev)
--
Benoit Izac
Philippe Weill
Le #26541732
Le 28/03/2020 à 20:44, Lulu a écrit :
[xp : fcolc,fcou ; fu2 :fcou ]
[supersedes : erreur dans mon sed]
Yo !
Je suis en train d'écrire un one-liner qui donne le nombre d'octets
envoyés par l'interface réseau :
$ cat /proc/net/dev
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
lo: 40750160 55083 0 0 0 0 0 0 40750160 55083 0 0 0 0 0 0
wlp2s0: 400565197 508500 0 142 0 0 0 0 177714515 445447 0 0 0 0 0 0
$ grep wlp2s0 /proc/net/dev | awk -F ' ' '{print $10}'
178064693
$ grep wlp2s0 /proc/net/dev | awk -F ' ' '{print $10}' | rev | sed -E 's/.../& /g' | rev
178 065 488
Je passe par rev et sed car je n'ai rien compris au formattage de chaîne avec
awk.
(rev est nécessaire pour que '1234' donne bien '1 234' et non '123 4')
Merci de votre aide.

[ ~]$ cat /tmp/testawk.awk
{ printf "%'dn",$0 }
[ ~]$ echo 123456789 | LC_NUMERIC="C" gawk -f /tmp/testawk.awk
123456789
[ ~]$ echo 123456789 | LC_NUMERIC="fr_FR.UTF-8" gawk -f /tmp/testawk.awk
123 456 789
[ ~]$ echo 123456789 | LC_NUMERIC="en_US.UTF-8" gawk -f /tmp/testawk.awk
123,456,789
[ ~]$
Benoit Izac
Le #26541736
Bonjour,
Le 29/03/2020 à 11:28, Philippe Weill a écrit dans le message
Je suis en train d'écrire un one-liner qui donne le nombre d'octets
envoyés par l'interface réseau :
$ cat /proc/net/dev
[...]
$ grep wlp2s0 /proc/net/dev | awk -F ' ' '{print $10}'
178064693
$ grep wlp2s0 /proc/net/dev | awk -F ' ' '{print $10}' | rev | sed
-E 's/.../& /g' | rev
178 065 488
Je passe par rev et sed car je n'ai rien compris au formattage de
chaîne avec
awk.
(rev est nécessaire pour que '1234' donne bien '1 234' et non '123
4')

[ ~]$ cat /tmp/testawk.awk
{ printf "%'dn",$0 }
[ ~]$ echo 123456789 | LC_NUMERIC="C" gawk -f /tmp/testawk.awk
123456789
[ ~]$ echo 123456789 | LC_NUMERIC="fr_FR.UTF-8" gawk -f
/tmp/testawk.awk
123 456 789
[ ~]$ echo 123456789 | LC_NUMERIC="en_US.UTF-8" gawk -f
/tmp/testawk.awk
123,456,789
[ ~]$

Cool, en one shot ça donne donc :
LC_NUMERIC=fr_FR.UTF-8 gawk '/wlp2s0/{printf "%'"'"'dn", $10}' /proc/net/dev
--
Benoit Izac
Lulu
Le #26541863
Le 29-03-2020, Benoit Izac
Le 29/03/2020 à 11:28, Philippe Weill a écrit dans le message
Je suis en train d'écrire un one-liner qui donne le nombre d'octets
envoyés par l'interface réseau :
$ cat /proc/net/dev
[...]
$ grep wlp2s0 /proc/net/dev | awk -F ' ' '{print $10}'
178064693
$ grep wlp2s0 /proc/net/dev | awk -F ' ' '{print $10}' | rev | sed
-E 's/.../& /g' | rev
178 065 488
Je passe par rev et sed car je n'ai rien compris au formattage de
chaîne avec
awk.
(rev est nécessaire pour que '1234' donne bien '1 234' et non '123
4')

[ ~]$ cat /tmp/testawk.awk
{ printf "%'dn",$0 }
[ ~]$ echo 123456789 | LC_NUMERIC="C" gawk -f /tmp/testawk.awk
123456789
[ ~]$ echo 123456789 | LC_NUMERIC="fr_FR.UTF-8" gawk -f
/tmp/testawk.awk
123 456 789
[ ~]$ echo 123456789 | LC_NUMERIC="en_US.UTF-8" gawk -f
/tmp/testawk.awk
123,456,789
[ ~]$

Cool, en one shot ça donne donc :
LC_NUMERIC=fr_FR.UTF-8 gawk '/wlp2s0/{printf "%'"'"'dn", $10}' /proc/net/dev

Super ! Ça roxe !!
Et j'économise le passage par grep, rev et sed...
J'ai mis ça dans un script bash, donc wlp2s0 est dans une variable
INTERFACE, j'ai googlé pour trouver qu'on peut passer une variable à
gawk avec la syntaxe suivante :
LC_NUMERIC=fr_FR.UTF-8 gawk -v k=$INTERFACE 'if ($1==k){printf "%'"'"'dn", $10/1000}' /proc/net/dev
avec la subtilité que INTERFACE doit être égale à wlp2s0: (avec le ":")
J'ai encore une question à propos de la syntaxe...
Que signifie la chaine "%'"'"'d" ?
Ce qui est très étonnant pour moi, c'est le nombre impair de « ' »
Merci encore à vous deux !
Nicolas George
Le #26541873
Lulu , dans le message écrit :
LC_NUMERIC=fr_FR.UTF-8 gawk -v k=$INTERFACE 'if ($1==k){printf "%'"'"'dn", $10/1000}' /proc/net/dev
Que signifie la chaine "%'"'"'d" ?

Rien du tout.
Ce qui est très étonnant pour moi, c'est le nombre impair de « ' »

Et c'est très juste. C'est parce qu'ils ne vont pas ensemble.
Le début, « "% », fait partie du script gawk.
Le ' termine la chaîne qui a commencé à « 'if »
Le « "'" » est une chaîne qui contient uniquement une apostrophe.
Le ' commence une chaîne qui se terminera avant /proc/net/dev.
La fin, « dn" », fait partie du script.
Il faut se rappeler que dans une chaîne entre ', seul ' est actif pour
marquer la fin de la chaîne, il n'y a pas d'échappement. Donc il est
impossible de faire figurer ' lui-même.
À la place, on assemble une chaîne entre ' puis une apostrophe seule
entre " puis une chaîne entre ' pour la fin du script. C'est pénible,
mais moins que de devoir penser à quoter tous caractères spéciaux pour
une chaîne en ".
Tout ceci se passe au niveau du shell. Ce que gawk voit, c'est :
« if ($1==k){printf "%'dn", $10/1000} » (avec des guillemets français
pour délimiter).
Benoit Izac
Le #26541894
Bonjour,
Le 30/03/2020 à 16:48, Lulu a écrit dans le message
J'ai mis ça dans un script bash, donc wlp2s0 est dans une variable
INTERFACE, j'ai googlé pour trouver qu'on peut passer une variable à
gawk avec la syntaxe suivante :
LC_NUMERIC=fr_FR.UTF-8 gawk -v k=$INTERFACE 'if ($1==k){printf
"%'"'"'dn", $10/1000}' /proc/net/dev
avec la subtilité que INTERFACE doit être égale à wlp2s0: (avec le ":")

Tu peux faire « '$1==k":" {…}' »
--
Benoit Izac
Lulu
Le #26542006
Le 30-03-2020, Nicolas George
Lulu , dans le message écrit :
LC_NUMERIC=fr_FR.UTF-8 gawk -v k=$INTERFACE 'if ($1==k){printf "%'"'"'dn", $10/1000}' /proc/net/dev

Que signifie la chaine "%'"'"'d" ?

Rien du tout.
Ce qui est très étonnant pour moi, c'est le nombre impair de « ' »

Et c'est très juste. C'est parce qu'ils ne vont pas ensemble.
Le début, « "% », fait partie du script gawk.
Le ' termine la chaîne qui a commencé à « 'if »
Le « "'" » est une chaîne qui contient uniquement une apostrophe.
Le ' commence une chaîne qui se terminera avant /proc/net/dev.

0K
La fin, « dn" », fait partie du script.
Il faut se rappeler que dans une chaîne entre ', seul ' est actif pour
marquer la fin de la chaîne, il n'y a pas d'échappement. Donc il est
impossible de faire figurer ' lui-même.

0K
À la place, on assemble une chaîne entre ' puis une apostrophe seule
entre " puis une chaîne entre ' pour la fin du script. C'est pénible,
mais moins que de devoir penser à quoter tous caractères spéciaux pour
une chaîne en ".
Tout ceci se passe au niveau du shell. Ce que gawk voit, c'est :
« if ($1==k){printf "%'dn", $10/1000} » (avec des guillemets français
pour délimiter).

Mais quel est l'intéret de passer une apostrophe ' au shell entre les
deux «commandes» gawk 'if ($1==k){printf "%' et 'dn", $10/1000}' /proc/net/dev
Cette "gymnastique" m'échappe complètement et me rend gawk complètement
obscur alors que je sens bien la puissance du machin.
(« Sans maîtrise, la puissance n'est rien » ©Pirelli ;-)
Lulu
Le #26542005
Le 30-03-2020, Benoit Izac
Le 30/03/2020 à 16:48, Lulu a écrit dans le message
J'ai mis ça dans un script bash, donc wlp2s0 est dans une variable
INTERFACE, j'ai googlé pour trouver qu'on peut passer une variable à
gawk avec la syntaxe suivante :
LC_NUMERIC=fr_FR.UTF-8 gawk -v k=$INTERFACE 'if ($1==k){printf
"%'"'"'dn", $10/1000}' /proc/net/dev
avec la subtilité que INTERFACE doit être égale à wlp2s0: (avec le ":")

Tu peux faire « if ($1==k":") {…} »

0K. Merci encore.
Benoit Izac
Le #26542013
Bonjour,
Le 31/03/2020 à 20:11, Lulu a écrit dans le message
Tout ceci se passe au niveau du shell. Ce que gawk voit, c'est :
« if ($1==k){printf "%'dn", $10/1000} » (avec des guillemets français
pour délimiter).

Mais quel est l'intéret de passer une apostrophe ' au shell entre les
deux «commandes» gawk 'if ($1==k){printf "%' et 'dn", $10/1000}' /proc/net/dev

Il n'est pas question de passer deux commandes à gawk mais de lui passer le
« %'d » pour qu'il formate correctement le nombre. Comme « ' » est
utilisé pour marquer le début et la fin de la commande gawk, on ne peut
pas utiliser « ' » simplement.
Le problème n'a donc rien à voir avec awk mais vient du shell qui
supprime les « ' » qui marquent le début fin de chaînes. Imaginons que
tu veuilles afficher « _'_ » dans la console, tout en utilisant « ' »
comme début/fin de chaîne, il y a plusieurs possibilités :
$ printf '%sn' '_'"'"'_' # encadrer le « ' » dans des « " »
$ printf '%sn' '_'''_' # échapper le « ' » avec «  »
Ou encore utiliser une extension bash qui permet d'interpréter le «  »
dans une chaîne :
$ printf '%sn' $'_'_'
$ printf '%sn' $'_47_'
--
Benoit Izac
Lulu
Le #26542260
Le 31-03-2020, Benoit Izac
Le 31/03/2020 à 20:11, Lulu a écrit dans le message
Tout ceci se passe au niveau du shell. Ce que gawk voit, c'est :
« if ($1==k){printf "%'dn", $10/1000} » (avec des guillemets français
pour délimiter).

Mais quel est l'intéret de passer une apostrophe ' au shell entre les
deux «commandes» gawk 'if ($1==k){printf "%' et 'dn", $10/1000}' /proc/net/dev

Il n'est pas question de passer deux commandes à gawk mais de lui
passer le « %'d » pour qu'il formate correctement le nombre. Comme
« ' » est utilisé pour marquer le début et la fin de la commande
gawk, on ne peut pas utiliser « ' » simplement.
Le problème n'a donc rien à voir avec awk mais vient du shell qui
supprime les « ' » qui marquent le début fin de chaînes. Imaginons
que tu veuilles afficher « _'_ » dans la console, tout en utilisant
« ' » comme début/fin de chaîne, il y a plusieurs possibilités :
$ printf '%sn' '_'"'"'_' # encadrer le « ' » dans des « " »
$ printf '%sn' '_'''_' # échapper le « ' » avec «  »
Ou encore utiliser une extension bash qui permet d'interpréter le «  »
dans une chaîne :
$ printf '%sn' $'_'_'
$ printf '%sn' $'_47_'

Pfff...
Je n'aurais jamais trouvé ça tout seul...
Merci pour la leçon ;-)
Poster une réponse
Anonyme