Comment extraire une sous-chaîne et des nombres uniquement en utilisant grep / sed

J’ai un fichier texte contenant à la fois du texte et des chiffres, je veux utiliser grep pour extraire uniquement les nombres dont j’ai besoin, par exemple, dans un fichier comme suit:

miss rate 0.21 ipc 222 stalls n shdmem 112 

Donc, disons que je veux seulement extraire les données pour le miss rate qui est 0.21 . Comment puis-je le faire avec grep ou sed? De plus, j’ai besoin de plus d’un numéro, pas seulement le miss rate après un miss rate . C’est-à-dire que je pourrais vouloir obtenir à la fois 0.21 et 112 . Un exemple de sortie peut ressembler à ceci:

 0.21 222 112 

Parce que j’ai besoin des données pour le complot ultérieur.

Utilisez plutôt awk :

 awk '/^miss rate/ { print $3 }' yourfile 

Pour le faire avec grep, vous avez besoin d’extensions non standard comme ici avec GNU grep utilisant PCRE (-P) avec lookbehind positif (? <= ..) et correspondance uniquement (-o):

 grep -Po '(?<=miss rate ).*' yourfile 

En utilisant le look spécial autour de regex sortingck \ K avec pcre engine avec grep :

 grep -oP 'miss rate \K.*' file.txt 

ou avec perl :

 perl -lne 'print $& if /miss rate \K.*/' file.txt 

La solution grep and- cut ressemblerait à ceci:

pour obtenir le 3ème champ pour chaque utilisation réussie de grep:

 grep "^miss rate " yourfile | cut -d ' ' -f 3 

ou pour obtenir le 3ème champ et le rest utiliser:

 grep "^miss rate " yourfile | cut -d ' ' -f 3- 

Ou si vous utilisez bash et “rate rate” ne se produit qu’une fois dans votre fichier, vous pouvez aussi simplement faire:

 a=( $(grep -m 1 "miss rate" yourfile) ) echo ${a[2]} 

${a[2]} est votre résultat.

Si “rate rate” se produit plus, une fois que vous pouvez parcourir la sortie de grep en lisant seulement ce dont vous avez besoin. (en bash)

Si vous voulez vraiment utiliser uniquement grep pour cela, alors vous pouvez essayer:

 grep "miss rate" file | grep -oe '\([0-9.]*\)' 

Il va d’abord trouver la ligne qui correspond, puis seulement les chiffres.

Sed pourrait être un peu plus lisible, cependant:

 sed -n 's#miss rate ##p' file 

Vous pouvez utiliser:

 grep -P "miss rate \d+(\.\d+)?" file.txt 

ou:

 grep -E "miss rate [0-9]+(\.[0-9]+)?" 

Ces deux commandes afficheront le miss rate 0.21 . Si vous voulez extraire le nombre uniquement, pourquoi ne pas utiliser Perl, Sed ou Awk?

Si vous voulez vraiment les éviter, cela fonctionnera peut-être?

 grep -E "miss rate [0-9]+(\.[0-9]+)?" g | xargs basename | tail -n 1 

Je crois

sed 's|[^0-9]*\([0-9\.]*\)|\1 |g' fiilename

fera le tour. Cependant, chaque entrée sera sur sa propre ligne si cela vous convient. Je suis sûr qu’il existe un moyen pour sed de produire une liste délimitée par des virgules ou des espaces, mais je ne suis pas un super maître de toutes les choses.