Comment puis-je diviser la sortie suivante, afin de stocker la valeur ttl
( 64
et 128
) dans une variable de boucle?
64 bytes from client2 (192.168.42.5): icmp_seq=1 ttl=64 time=0.324 ms 64 bytes from server (192.168.42.6): icmp_seq=1 ttl=128 time=0.663 ms
Merci d'avance
Cordialement
4 Réponses :
Quelque chose comme:
stuff | sed -E 's/.*[[:space:]]ttl=([^[:space:]]+).*/\1/'
L'expression régulière est:
.*
correspond à tout[[:space:]]
un seul espacettl=
ttl =([^[:space:]]+)
capture un groupe d'un ou plusieurs caractères non espace.*
le reste de la chaîne Ensuite, la fin \1
remplace la ligne entière par la valeur capturée
Le pipeline suivant est un moyen d'obtenir les éléments spécifiques que vous souhaitez. Le grep
extrait uniquement le bit ttl=something
et le cut
supprime le ttl=
:
pax> ( ...> echo '64 bytes from client2 (192.168.42.5): icmp_seq=1 ttl=64 time=0.324 ms' ...> echo '64 bytes from server (192.168.42.6): icmp_seq=1 ttl=128 time=0.663 ms' ...> ) | awk ' ...> / bytes from / { ...> gsub(/ttl=/, "", $7) ...> gsub(/\(/, "", $5) ...> gsub(/\):/, "", $5) ...> print $4" "$5" "$7 ...> }' | while read NAME IP TTL ; do ...> echo "Machine ${NAME} with IP ${IP} has TTL ${TTL}" ...> done Machine client2 with IP 192.168.42.5 has TTL 64 Machine server with IP 192.168.42.6 has TTL 128
Vous pouvez le voir dans la transcription suivante:
:: ping -c 5 127.0.0.1 | grep -o 'ttl=[^ ]*' | cut -c5- 64 64 64 64 64
Ou à partir d'une vraie commande ping
:
pax> printf 'AA ttl=64 BB\nCC ttl=128 DD\n' AA ttl=64 BB CC ttl=128 DD pax> printf 'AA ttl=64 BB\nCC ttl=128 DD\n' | grep -o 'ttl=[^ ]*' | cut -c5- 64 128
Il n'y a aucun doute que d' autres pipelines peuvent faire la même chose (peut-être même plus simple) mais c'est le premier qui m'est venu à l'esprit. L'indicateur grep -o
est assez pratique pour afficher uniquement le texte correspondant plutôt que la ligne entière.
Par exemple, une solution plus complète pour gérer cette sortie peut être la suivante:
grep -o 'ttl=[^ ]*' | cut -c5-
Le awk
sélectionne d'abord les enregistrements corrects, puis modifie les champs afin que vous n'obteniez pas les éléments supplémentaires (comme le ttl=
ou les parenthèses autour de l'adresse IP). Il imprime ensuite trois des champs et l' envoie à travers un while
en boucle à les traiter comme des unités simples (une ligne de réponse ping par unité).
Le corps de la boucle affiche simplement les détails, mais vous pouvez ajuster le comportement pour faire autre chose si vous le souhaitez.
Vous pouvez utiliser des expressions régulières bash:
do something with ttl value 64 do something with ttl value 128
les sorties
while IFS= read -r line; do if [[ $line =~ "ttl="([[:digit:]]+) ]]; then ttl=${BASH_REMATCH[1]} echo "do something with ttl value $ttl" fi done <<END 64 bytes from client2 (192.168.42.5): icmp_seq=1 ttl=64 time=0.324 ms 64 bytes from server (192.168.42.6): icmp_seq=1 ttl=128 time=0.663 ms END
La variable de tableau BASH_REMATCH
contient le texte correspondant aux parenthèses de capture. De plus, le 0ème index de ce tableau contient la partie de la chaîne qui correspond à l'ensemble de l'expression régulière, par exemple "tty = 64" pour la première ligne.
Merci beaucoup pour toutes vos réponses !!!
Je pense que c'est suffisant pour avoir une idée juste pour commencer.
awk -F"[ =]" '{print $9}'
voir: stackoverflow.com/a/57916912/390913