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

Permalänk
Hedersmedlem

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...

Visa signatur

Asus ROG STRIX B550-F / Ryzen 5800X3D / 48 GB 3200 MHz CL14 / Asus TUF 3080 OC / WD SN850 1 TB, Kingston NV1 2 TB + NAS / Corsair RM650x V3 / Acer XB271HU (1440p165) / LG C1 55"
Mobil: Moto G200

Permalänk
Medlem

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?

Visa signatur

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

Permalänk
Hedersmedlem

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å.

Visa signatur

Asus ROG STRIX B550-F / Ryzen 5800X3D / 48 GB 3200 MHz CL14 / Asus TUF 3080 OC / WD SN850 1 TB, Kingston NV1 2 TB + NAS / Corsair RM650x V3 / Acer XB271HU (1440p165) / LG C1 55"
Mobil: Moto G200

Permalänk
Medlem

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/'

Permalänk
Hedersmedlem

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)/'

Visa signatur

Asus ROG STRIX B550-F / Ryzen 5800X3D / 48 GB 3200 MHz CL14 / Asus TUF 3080 OC / WD SN850 1 TB, Kingston NV1 2 TB + NAS / Corsair RM650x V3 / Acer XB271HU (1440p165) / LG C1 55"
Mobil: Moto G200