21x9.org | System Administration | Home Automation | Smart Home
03.01.2016

Command Line Adventues: AWK

Wenn ich mich recht erinnere haben wir in den vorangegangenen CLI-Adventures awk bisher immer nur verwendet um eine bestimmte Stelle (nennen wir es Spalte) einer Zeile herauszulösen. awk kann jedoch deutlich mehr, zum Beispiel Rechnen und Systembefehle ausführen.

cat speedtest.txt | grep Download | awk ‘{SUM += $2} END {system(“cat speedtest.txt | grep Download | wc -l” | getline LINES);print SUM/LINES}’ 2> /dev/null

Was passiert da? Nun, ich denke, ich sollte das ein wenig ausführlicher Erläutern. Mein Internet zuhause schwächelt. Schon länger, aber es waren gefühlt immer mind. 50 MBit (von 100), damit habe ich mich zufrieden gegeben. Mittlerweile fühlt es sich aber eher wie 25 MBit an. Bevor ich mich beim Provider (netcologne) beschwere wollte ich das aber genau wissen. netcologne blockt in der Regel alle Speedtests ab, die nicht mit netcologne-Servern durchgeführt wurden. Für http://speedtest.net stellt netcologne einen Testserver bereit. Unter https://github.com/sivel/speedtest-cli gibt es ein Kommandozeilentool für speedtest.net, es steht außerdem als Debian-Paket zur Verfügung:

apt-get install speedtest-cli
speedtest-cli –server 6601

6601 ist die Server-ID des netcologne-Speedtest-Servers (siehe http://www.speedtest.net/speedtest-servers.php). Natürlich sollte man einen Speedtest über einen längeren Zeitraum durchführen. Und natürlich habe ich keine Lust dies jede Stunde selbst zu tun. Also ein kleines Script:

#!/bin/bash

cd /home/gpkvt
date >> speedtest.txt
/usr/local/bin/speedtest-cli –server 6601 | grep ‘Download\|Upload\|Hosted\|Testing from’ >> speedtest.txt
echo “———————————–” >> speedtest.txt

Per Cron läuft das jetzt jede Stunde und erzeugt pro Lauf folgenden Eintrag:

Sun Jan 3 12:00:01 CET 2016
Testing from NetCologne GmbH (xx.xx.xx.xx)…
Hosted by NetCologne (Cologne) [5.04 km]: 20.8 ms
Download: 24.14 Mbit/s
Upload: 4.59 Mbit/s
———————————–

Natürlich will ich netcologne jetzt nicht mit einer Datei mit hunderten von Zeilen bewerfen, sondern einen Durchschnittswert melden. Die awk-Zeile von oben ermöglicht genau das:

cat speedtest.txt | grep Download gibt die Downloadgeschwindigkeiten aus. awk ‘{SUM += $2} zählt die MBit/s-Werte zusammen. END sorgt dafür, dass eine Aktion ausgeführt wird, wenn keine weiteren Zeilen von speedtest.txt an awk übergeben werden. {system(“cat speedtest.txt | grep Download | wc -l” | getline LINES) zählt die Anzahl der Download-Zeilen in speedtest.txt zusammen und speichert den Wert als LINES. ;print SUM/LINES}’ teilt SUM durch LINES und gibt das Ergebnis aus. 2> /dev/null unterdrückt eine Shell-Fehlermeldung.

Das Ergebnis, meine durchschnittliche Downloadrate (in MBit/sek.) in den letzten 3 Tagen:

24.9871

Update: Auf [[https://twitter.com/jselzer/status/683648459837173760|Twitter]] wurde ich gefragt, ob der system-Part nicht auch eleganter zu lösen wäre. Ja:

cat speedtest.txt | grep Download | awk ‘{LINES++;SUM += $2} END {print SUM/LINES}’

Hier zählt awk gleich die Anzahl der Zeilen (LINES++) mit und nutzt diesen Wert dann. Der system-Aufruf kann dann komplett entfallen. Neben der handlicheren Zeilenlänge hat dieses Vorgehen natürlich auch noch den Vorteil, dass sich zwischen der Summenbildung (SUM) und dem system-Aufruf die Anzahl der gefundenen Zeilen in der speedtest.txt nicht ändern können.

Noch handlicher ginge es dann noch, wenn man auf cat und grep verzichtet:

awk ‘/Download/ {LINES++;SUM += $2} END {print SUM/LINES}’ speedtest.txt

Hier sucht awk selbst nach Download.

Tags: linux cli awk

Tags

linux cli awk

Feeds

Atom 1.0 RSS JSON
  • Datenschutz
  • Impressum
  • Archiv