Page 1 of 1

Wert aus Programmausgabe extrahieren

Posted: 2008-01-13 00:13
by mstuebner
Moin,

der Titel ist ein bischen eckig, weil es mit einem Wort halt nicht eindeutig zu schreiben ist. Ist aber an sich ganz einfach.

Ich brauche aus der Ausgabe von IPTables eine Zahl aus dem Ergebniss, weiss aber nicht wie ich diese wirklich sicher extrahieren kann.
IPTables liefert z.B. folgende Ausgabe:

Code: Select all

Chain PREROUTING (policy ACCEPT 25278 packets, 1587962 bytes)
    pkts      bytes target     prot opt in     out     source               destination
  808998 46742418 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0
   10129  1764923 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain OUTPUT (policy ACCEPT 128591 packets, 171403796 bytes)
    pkts      bytes target     prot opt in     out     source               destination
 1215183 1743874456 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0
   10274  1132890 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0
Aus dieser Ausgabe benötige ich aus den entsprechenden Zeilen die Byteausgaben, also die zweite Zahl. Die Formatierung der IPTables Ausgabe
wird leider mit Leerzeichen formatiert. Wie man aber sehen kann variiert die Anzahl der Leerzeichen, weshalb dem Ganzen mit cut nicht beizukommen ist,
da auch nicht feststeht, an welcher Position der zweite Zahlwert beginnt (sonst wäre es einfach).

Hat dazu jemand eine zündende Idee?

Re: Wert aus Programmausgabe extrahieren

Posted: 2008-01-13 00:26
by Joe User
Mit sed und/oder gawk sollte es relativ einfach zu bewerkstelligen sein...

Re: Wert aus Programmausgabe extrahieren

Posted: 2008-01-13 00:35
by bernsteinkater

Code: Select all

awk '{print $2}' |egrep -v '[a-z,A-Z]'
sollte klappen ausser bei der "Zusammenfassungszeile" aber das kann man sich ja nochmal separat ausrechnen.

Re: Wert aus Programmausgabe extrahieren

Posted: 2008-01-13 00:41
by mstuebner
bernsteinkater wrote:

Code: Select all

awk '{print $2}' |egrep -v '[a-z,A-Z]'
sollte klappen ausser bei der "Zusammenfassungszeile" aber das kann man sich ja nochmal separat ausrechnen.
Vielen Dank, allein awk bringt das Ergebnis was ich brauche, nun muss ich nur noch analysieren was die Kommandozeile tut. ;-)

Re: Wert aus Programmausgabe extrahieren

Posted: 2008-01-13 15:13
by mstuebner
mstuebner wrote:
bernsteinkater wrote:

Code: Select all

awk '{print $2}' |egrep -v '[a-z,A-Z]'
sollte klappen ausser bei der "Zusammenfassungszeile" aber das kann man sich ja nochmal separat ausrechnen.
Vielen Dank, allein awk bringt das Ergebnis was ich brauche, nun muss ich nur noch analysieren was die Kommandozeile tut. ;-)
Also daran bin ich gescheitert. Ich bin nicht in der Lage diesen aufruf von awk mit der Beschreibung in den Man-Pages zusammen zu bringen. Da muss wohl Google nochmal herhalten.

Trotzdem bin ich so mutig noch nach einem zweiten Fall zu fragen:

Und zwar prinzipiell das selbige für den Diskcspace, problematisch (für mich) ist hier nur, dass das Volume einen recht langen Namen bekommen hat und df daher die Ausgabe umbricht, wie folgt:

Code: Select all

Dateisystem          Größe Benut  Verf Ben% Eingehängt auf
/dev/mapper/VolGroup00-LogVol00
                      224G   42G  171G  20% /
/dev/sda1              99M   16M   79M  17% /boot
...und ich daher den zweiten Wert der zweiten Zeile bräuchte. Durch den Umbruch steht in der zweiten Zeile auch nichts unveränderliches, so dass man die Zeile ja leider nicht mit einem GREP zu greifen bekommt. Ich habe keinen Zweifel dass das für (e)grep, awk, sed, regex Fachleute kein Problem darstellt, leider bin ich keiner von diesen.

Re: Wert aus Programmausgabe extrahieren

Posted: 2008-01-13 16:19
by mstuebner
mstuebner wrote:

Code: Select all

Dateisystem          Größe Benut  Verf Ben% Eingehängt auf
/dev/mapper/VolGroup00-LogVol00
                      224G   42G  171G  20% /
/dev/sda1              99M   16M   79M  17% /boot
Mal ein Versuch meinerseits:

Code: Select all

df -m|sed 1d|awk '{print $2}'
ergibt leider

Code: Select all

42G
99M
Kleiner Hinweis? Was ich bräuchte wäre ein "Lösche Zeile 1 und 3" aber ein "sed 1d|sed 3d" arbeitet ja immernoch auf dem selben Arbeitsspeicher, und gibt daher erst die Zeilen 2+3 und dann die Zeilen 1+2 aus.

Re: Wert aus Programmausgabe extrahieren

Posted: 2008-01-13 16:34
by Joe User

Code: Select all

df -m | sed 1d | sed 's#
s+([0-9]+.*)#1#' | awk '{print $2}'
Der Zeilenumbruch ist wichtig!

Re: Wert aus Programmausgabe extrahieren

Posted: 2008-01-13 17:50
by mstuebner
Joe User wrote:

Code: Select all

df -m | sed 1d | sed 's#
s+([0-9]+.*)#1#' | awk '{print $2}'
Der Zeilenumbruch ist wichtig!
Also wenn ich da genauso übernehme wird folgendes ausgegeben:

Code: Select all


42G
99M
Prinzipiell würde es ja auch die Kombination der sed Optionen D und P bringen, nur irgendwie begreife ich die Syntax nicht.

D die erste Zeile im Arbeitsspeicher von sed wird gelöscht und die nächste Zeile wird gelesen;
P die erste Zeile im Arbeitsspeicher wird in die Standardausgabe geschrieben

Re: Wert aus Programmausgabe extrahieren

Posted: 2008-01-13 18:29
by bernsteinkater
Es gibt sich viele Moeglichkeiten aber die einfachste ist wohl NF-3 zu benutzen ("NF = number of fields in the current record") und die ersten beiden Zeilen auszuschneiden.

Code: Select all

df -h|sed 1,2d|awk '{print $(NF-3)}'
Das ist aber sehr speziell und nicht allgemein gueltig. Wenn Du zB weitere VolumeGroups anlegst wird das nicht mehr funktionieren.

Re: Wert aus Programmausgabe extrahieren

Posted: 2008-01-13 18:55
by Joe User
Oops, kleiner Denkfehler meinerseits, folgendes sollte passen:

Code: Select all

df -m | sed 1d | sed 's#
s+([0-9]+.*)#dummy 1#' | awk '{print $2}'

Re: Wert aus Programmausgabe extrahieren

Posted: 2008-01-13 18:59
by mstuebner
bernsteinkater wrote:Das ist aber sehr speziell und nicht allgemein gueltig. Wenn Du zB weitere VolumeGroups anlegst wird das nicht mehr funktionieren.
Das ist kein Problem.

Es gibt wirklich tausend Wege ich bin jetzt mal auf folgendes gekommen:

Code: Select all

df -m|sed -n '3'p|awk '{print $2}'
Danke euch beiden für eure Hilfe!

Re: Wert aus Programmausgabe extrahieren

Posted: 2008-01-13 20:45
by Joe User
mstuebner wrote:Es gibt wirklich tausend Wege ich bin jetzt mal auf folgendes gekommen:

Code: Select all

df -m|sed -n '3'p|awk '{print $2}'
Und wenn sich die Partitionierung ändert, musst Du das Script wieder anpassen. Mit meiner Lösung ist das nicht nötig...

Re: Wert aus Programmausgabe extrahieren

Posted: 2008-01-13 22:45
by mstuebner
Joe User wrote:Und wenn sich die Partitionierung ändert, musst Du das Script wieder anpassen. Mit meiner Lösung ist das nicht nötig...
Das mag richtig sein, nur kann ich sie nicht nachvollziehen und das Ergebnis was ich beim Ausführen erhalten habe war nicht wie erwartet. Die Partitionierung des Servers wird sich überigens erst bei dessen Entsorgung ändern, das ist also soweit kein Problem. Danke nochmal.

Re: Wert aus Programmausgabe extrahieren

Posted: 2008-01-13 23:21
by Joe User
Und was machst Du, wenn sich die Reihenfolge der Ausgabe von df ändert?

Re: Wert aus Programmausgabe extrahieren

Posted: 2008-01-13 23:37
by mstuebner
Joe User wrote:Und was machst Du, wenn sich die Reihenfolge der Ausgabe von df ändert?
1. Wieso sollte sie das?
2. Dein Code ergibt z.B. bei einem df -m von:

Code: Select all

Dateisystem          1M-Blöcke   Benutzt Verfügbar Ben% Eingehängt auf
/dev/mapper/VolGroup00-LogVol00
                        293641     24151    254333   9% /
/dev/sda1                   99        16        79  17% /boot
/usr/tmpDSK                485        67       393  15% /tmp

Code: Select all


24151
99
485
statt nur 24151, also auch nicht den Wert den ich brauchte. Wie schon geschrieben, an den Platten ändert sich nichts und wenn ich Deinen Code a. verstehen und b. er das gewünschte Ergebnis geben würde, dann tät ich ihn auch gerne benutzen.

Re: Wert aus Programmausgabe extrahieren

Posted: 2008-01-13 23:48
by Joe User
Mein zweiter Oneliner zeigt die richtigen Werte an, der Erste hatte einen Bug.

Kurzbeschreibung der Befehle:


Diskfree in MB.

Code: Select all

df -m
Lösche die erste Zeile vorheriger Ausgabe.

Code: Select all

sed 1d
Ersetze die Zeichenfolge "mindestens ein Space" (s+) vor der Zeichenfolge "mindestens eine Ziffer zwischen 0 und 9" ([0-9]+) gefolgt von "0 oder mehr beliebige Zeichen" (.*) durch die Zeichenfolge "dummy" in der vorherigen Ausgabe.

Code: Select all

sed 's#
s+([0-9]+.*)#dummy 1#'
Zeige aus jeder Zeile die jeweils zweite Spalte an.

Code: Select all

awk '{print $2}'
Genauer steht es wie immer in den jeweiligen manpages.

Re: Wert aus Programmausgabe extrahieren

Posted: 2008-01-13 23:56
by mstuebner
Joe User wrote:Mein zweiter Oneliner zeigt die richtigen Werte an, der Erste hatte einen Bug.
Ich hatte den von 18:55 versucht. Danke für die Ausführliche Erläuterung. Schrittweise ausprobiert weiss ich jetzt, dass ich an folgendem scheiter:

Code: Select all

sed 's#
s+([0-9]+.*)#dummy 1#'
...da ich entweder nicht weiss ich wie ich das mit dem Zeilenumbruch benutzen kann oder sonst einen Fehler mache, zumind. ist die Ausgabe mit dem obigen Code exakt identisch mit der Ausgabe nach dem "sed 1d".
Joe User wrote:Genauer steht es wie immer in den jeweiligen manpages.
Die ich auch wie immer ausgiebig bemühe, welche mir hier aber dank ihrer Oberflächlichkeit nicht wirklich die Erleuchtung brachten. Gut war jedoch folgende Site http://www.gnulamp.com/sed.html

Re: Wert aus Programmausgabe extrahieren

Posted: 2008-01-14 00:01
by Joe User
Der Zeilenumbruch muss wie gepostet exakt nach dem ersten Backslash sein, andernfalls funktioniert es nicht.

Re: Wert aus Programmausgabe extrahieren

Posted: 2008-01-14 00:07
by Joe User
Sehr empfehlenswert: http://sed.sourceforge.net/