0
votes

Divisez le contenu d'une chaîne en utilisant comme délimiteur le "="

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


2 commentaires

awk -F"[ =]" '{print $9}'


voir: stackoverflow.com/a/57916912/390913


4 Réponses :


1
votes

Quelque chose comme:

stuff | sed -E 's/.*[[:space:]]ttl=([^[:space:]]+).*/\1/'

L'expression régulière est:

  • .* correspond à tout
  • [[:space:]] un seul espace
  • ttl= 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


0 commentaires

2
votes

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.


0 commentaires

2
votes

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.


0 commentaires

0
votes

Merci beaucoup pour toutes vos réponses !!!

Je pense que c'est suffisant pour avoir une idée juste pour commencer.


0 commentaires