grep/sed/awk: få ut enbart det som matchar ett regex

Trädvy Permalänk
Hedersmedlem
Plats
Uppsala
Registrerad
Jul 2001

grep/sed/awk: få ut enbart det som matchar ett regex

Halloj
Skrev ihop en oneliner för att få snyggare resultat ur iperf, t ex:

echo "$(date '+%Y-%m-%d %H:%M:%S') - `iperf -p 1641 -c tptest.arrowhead.se -t 20 2>/dev/null | grep '0.0-' | awk '{print $7}'` Mbit/s"

Problemet är att $7 inte alltid är rätt, t ex så skrev den senast ut "MBytes Mbit/s".
grep -P '(\d.\d{2}) Mbits\/sec'
får ut exakt det jag vill, MEN det markerar ju bara det som matchar (om man har --colour på), allt annat som jag vill få bort står ju kvar ändå. Hur får man nåt av dessa verktyg att enklast skriva ut exakt det som matchar? I den här fallet vill jag ha ut "8.08" av
"[ 3] 0.0-10.0 sec 9.62 MBytes 8.08 Mbits/sec".

Har faktiskt grubblat på detta länge (långt innan just det här fallet alltså), och då jobbat runt det på diverse fula sätt...

X370 Taichi / R7 1700 @ 3.75 GHz 1.2 V / 2x8 GB 3200 MHz CL16 / MSI GTX 1070 Gaming, OC / Samsung 960 EVO 500 GB / Corsair RM650x
LG G6 (H870)

Trädvy Permalänk
Medlem
Plats
Malmö
Registrerad
Mar 2002

echo -n "`date '+%Y-%m-%d %H:%M:%S'` - " && iperf -p 1641 -c tptest.arrowhead.se -t 20 2>/dev/null|grep "0.0-"|cut -d" " -f12-

Fungerar detta bättre?

01001000 01100001 01110010 00100000 01100100 01110101 00100000 01110100 01110010 10000110 01101011 01101001 01100111 01110100 00111111 00100000 00111010 00101001

Trädvy Permalänk
Hedersmedlem
Plats
Uppsala
Registrerad
Jul 2001

Jepp, funkar fint, men det borde väl kunna få samma problem det med?
Tänkte att så länge som raden innehåller "x.xx Mbit" ska det funka. I just det här fallet går det ju, men jag tänkte läsa mig till framtida småprylar också.

X370 Taichi / R7 1700 @ 3.75 GHz 1.2 V / 2x8 GB 3200 MHz CL16 / MSI GTX 1070 Gaming, OC / Samsung 960 EVO 500 GB / Corsair RM650x
LG G6 (H870)

Trädvy Permalänk
Medlem
Plats
::1
Registrerad
Jun 2005

echo "$(date '+%Y-%m-%d %H:%M:%S') - `iperf -p 1641 -c tptest.arrowhead.se -t 20 2>/dev/null | sed -e 's/.*MBytes[[:space:]]\([[:digit:]]*\..*\)/\1/'

Kanske? I sed använder du \1 - \9 för att återinföra tidigare matchade delar av regex omgivna av ( och ) (escapade med '\' ovan). Se man-sidan för mer info.

EDIT: En lite mer formatsäker version men antagligen svårare att läsa vid första anblicken:

sed 's/\(.*\)[[:space:]]\+\([[:digit:]]\+\.[[:digit:]]\+\)[[:space:]]*\(Mbit.*\)/\2/'

Trädvy Permalänk
Hedersmedlem
Plats
Uppsala
Registrerad
Jul 2001

Hehe, bara lite
Fixade detta med perl, ska nog börja använda det oftare istället för sed, eftersom jag älskar perls regular expressions

echo "$(date '+%Y-%m-%d %H:%M:%S') - $(iperf -p 1641 -c tptest.arrowhead.se -t 20 2>/dev/null | grep '0.0-' | \ perl -pe 's/.*(\d\.\d{2}) Mbits.*/\1/g') Mbit/s"


Ska se om jag inte kan få bort grep-raden också, inte så värst snyggt med den. Inte för att det blir snyggt utan heller, men ändå.
Edit: Löste det också, efter lite hakkande på hur perl funkar.

iperf -p 1641 -c tptest.arrowhead.se -t 20 2>/dev/null | perl -ne '/(\d\.\d{2}) Mbits/ && print $+'

Skriver ut enbart siffrorna, sen är det bara lägga till datum och ev. enhet.

Edit: Snyggare perl-rad igen:
iperf -p 1641 -c tptest.arrowhead.se -t 20 2>/dev/null | perl -ne 'print $1 if /(\d\.\d{2} Mbits\/s)/'

X370 Taichi / R7 1700 @ 3.75 GHz 1.2 V / 2x8 GB 3200 MHz CL16 / MSI GTX 1070 Gaming, OC / Samsung 960 EVO 500 GB / Corsair RM650x
LG G6 (H870)