Grep über eine Zahl

D

doonot

Mitglied
Hallo Zusammen

Ich hoffe schwer ihr könnt mir helfen, ich stehe shcon seit Tagen am Anschlag. Mir wird alle 2 min vom Cronjob ein File generiert mit Zahlen drin. diese muss ich ja mit nawk .... auswählen. anschliessend muss ich jede Zeile mit grep durchsuchen. Ich möchte das er mir alle Zahlen die grösser als 3000 anzeigt. anschliessend mache ich ein wc -l darüber, welches mir die Anzahl angibt, wieviele Zahlen über 3000 sind.

(Später vergleiche ich diesen WC wert mit 5, wenn er grösser als 5 ist, sendet er automatisch ein SMS an mich)

Eigenltich habe ich schon alles, bis auf das grep, welches Zahlen die grösser als 3000 ausgibt. Könnt ihr mir hier helfen? Vielen Dank jetzt schon an alle, die sich dafür den Kopf zerbrechen.
 
Hallo
grep selbst kann keinen Vergleich durchführen.

Du kannst aber die Ausgabe von grep in einen Shell-test vergleichen, dieser kann aber nur mit Integer arbeiten.
Aber warum filterst du das nicht gleich in awk aus?

Gruß Wolfgang
 
Schade, wie meinst du direkt mit nawk?

Würde es evt so gehen?
Code:
nawk '{print $14 }' /var/opt/xsam/scripts/tpi_response/tpi_response_$DATE2 | grep -V "^[1-9]" "[1-9]." "[1-9].." "[1-2]..." | wc -l > $WC_NEW
 
Hallo

Wenn ich hier mal nur Feld 1 betrachte und Ausgabe von Zahlen größer 10 bei mehr Vorkommen als 5 wünsche:
Code:
awk ' $1 > 10 {a++}END{if (a > 5) {print "Es wurden:" ,a, "Zahlen > 10 gefunden"}} ' inputfile

Erspart wc und grep, geht aber von echten Zahlen im Feld 1 aus.

Gruß Wolfgang
 
Schade ich habe etwa ein 100 Zeiliges Script, und du machst es mir ein einer Zeile, vielen Dank man.

Ist es auch möglich, das er jeweils nur die letzten 2 Minuten von dem Logfile aussucht und diese dann auf 3000 testet, auf 5 zählt und ein sms sendet?
 
Wenn die letzten 2 Minuten immer die gleiche menge haben kannst du "tail" benutzen.
tail -n10 liefert die letzten 10 zeilen zurück. Oder du lässt das cron 2 mal schreiben, einmal > last und einmal >> all. das kannst d mittels tee
 
Leider sind nicht immer gleich viele eintragungen drin. es ist ein logfile eines servers. deshalb hat es bei mir mit tail nicht geklappt, da dann nicht alle files gecheckt werden.

vieleicht irgendwie date - 2 min?
 
Hallo

Um das zu realisieren miusst du entweder eine Marke setzen, oder den letzten Status zwischenspeichern.
AWK kennt die eingelesene Zeilenzahl als Variable NR.
Wenn du diese in eine Datei zwischenspeicherst, kannst du den Wert an awk mitgeben.
Dann führst du einfach solange getline aus, bis du die Position gefunden hast.
Das ist allerdings nicht sauber, da ja z.B. die Datei zwischendurch gelöscht /geleert sein kann.

Um die Zeit zu filtern, muss dein Logfile diese selbst mitführen.
Dann würe ich lieber perl verwenden, da das mit entsprechendem Modul auch Zeitstrings umrechnen kann.

Mit regexp auf eine Zeit zu matchen ist bei Logfiles sinnlos, da du nicht weißt, ob es einen Eintrag gab.

Ist alles abhängig vom Aufbau deiner Log und deiner Situation (wer greift wann und wie auf diese Datei zu, bzw.ändert oder löscht sie gar)

Gruß Wolfgang
 
Ich bin immernoch am awk befehl, ich möchte anstatt eines print, ein mailx, aber ich bringe es nicht hin. Hier mein Vorschlag:

Code:
#!/usr/bin/bash

MAILLIST="mail"
SMSLIST="sms-number"
MAILTEXT="responses on (`hostname`) needed more than 3 Seconds in the last 2 Minutes, Check System!"
ERRORTEXT="response Time on (`hostname`) needs more than 3 Seconds!"
MAILHEADER="TPI-Response Time"


awk ' $1 > 3000 {a++}END{if (a > 5) {echo $MAILTEXT | mailx -s "$MAILHEADER" $SMSLIST }}' testlogfile

warum steht andauern awk: illegal statement? was mache ich nur falsch :(?

könnte man das ganze auhc noch auseinander nehemen? also zuerst ein awk, und auf einer neuen zeile eine if-else schleife, da ich möchte, dass das ,a, den wert 1 bekommt, wenn es kleiner als 5 ist.

Ich danke euch ihr unixgötter :)
 
Zuletzt bearbeitet:
Hallo

Shellvariablen übergibst du an awk via --assign oder -v
Beispiel:
Code:
VAR="Das ist ein String der angehängt werden soll"
awk -v V="$VAR" '{print $0, "  ",V}' input

Hängt an jede Zeile den String aus der Shellvar VAR an.

Deinen fehler bekommst du, weil es unter awk dieses echo nicht gibt!

Um eine Mail zu versenden verwende einfach die stdout mit einer pipe.
e.g.
Code:
...
END{
printf "%s\n%s\n%s\n\n%s\n",
        "From: user@home.tld",
        "To: "$1,
        "Subject: Mein Subject",
         "Hier der Text der Mail..." | /usr/bin/sendmail -t

Das dritte Problem deiner neuen Wertzuweisung ist mir nicht ganz klar, aber du kannst doch jegliche Variablen einfach neu setzen.
Code:
if (a > 5) { a=1;...}

Was du damit bezwecken willst, ist mir aber nicht klar.

Gruß Wolfgang
 
also ich erkläre nochmals die funktion meines scriptes. im cronjob erstelle ich all 2 minuten ein file mit zahlen (antwortszieten eines servers), wenn diese antworts zeiten über 3000 sind sollte ich ein sms/mail bekommen.
um nicht bei jedem anwortszeitausschlag eine sms zu bekommen, möchte ich das das script zuerste die über 3000 auf 5 hinaufzählt und erst dan schreibt.

zum schluss möchte ich die variable, welche sagt, wieviel über 3000 sind, auf 1 zurück reseten, damit beim nächsten lauf in 2 minuten alles wieder von vorne beginnt. ich versuche deine lösung gleich einmal :)

vielen dank für deine arbeit, ich melde mich gleich.
.
.
.
EDIT (autom. Beitragszusammenführung) :
.

ah nein, ich möchte nicht noch zusätzlich eine variable, welche angehängt werden soll, ich möchte nur das ursprüngliche ,a, später an die ifschleife übergeben, ohne das diese den wert verliert. versteht ihr?
 
Zuletzt bearbeitet:
Wenn dein Script neu gestartet wird, ist auch a neu initialisiert.
a ist ja nur der Zähler, welcher am Ende ausgewertet wird.

Du hast offensichtlich nicht verstanden, was ich erklären wollte.
Das Beispiel mit der angehängten Variable sollte nur zeigen, wie du Shellvariablen (e.g. dein Mailtext) an awk übergeben kannst.
 
aber weshalb geht meine lösung nicht, ich möchte, dass es diemeldung an die vordefinierten variablem schickt, kann man das nicht so hinbiegen, damit es funktioniert?

deine erste lösung würdemir darum schon sehr gefallen, da es kurz und bündig ist, (jedoch ist alles so verschachtelt, was es sehr kompolizert macht) :(
.
.
.
EDIT (autom. Beitragszusammenführung) :
.

awk -v ML="$MAILLIST" SL="$SMSLIST" MT="$MAILTEXT" MH="$MAILHEADER" ' $1 > 3000 {a++}END{if (a > 5) {echo MT | mailx -s MH SL }}' testlogfile

naja das geht au nett :(
 
Zuletzt bearbeitet:
Ich sagte schon, es gibt kein echo in awk!
Verwende einfach print oder printf!

Um mehrere Variablen zususweisen verwende einfach -v Var="erster Wert" -v VAR2="Zweiter Wert"...
 
Code:
awk -v ML="MAILLIST" -v SL="SMSLIST" -v MT="MAILTEXT" -v MH="MAILHEADER" ' $1 > 3000 {a++}END{if (a > 5) {print MT | mailx -s MH SL }}' testlogfile

wenn ich es so mache zählt es mir folgendes auf
Code:
awk: syntax error near line 1
awk: bailing out near line 1
 
Zuletzt bearbeitet:
Warum nur so kompliziert?

Wenn du auf Werte von Shellvariablen zugreifen willst, verwende den $.
Werte der eigenen awk-variablen ohne $!
 
das ist ja nicht kompliziert, es ist nur so wies du mir sagst. ich weiss ich bin ein grünschnabel, aber verdammt, es muss doch funktionieren.

auch nur wenn ich mit enem print den mailtext ausgeben will, funktioniert es nicht.

Code:
awk -v ML="$MAILLIST" -v SL="$SMSLIST" -v MT="$MAILTEXT" -v MH="$MAILHEADER" ' $1 > 3000 {a++}END{if (a > 5) {print MT}} ' testlogfile
.
.
.
EDIT (autom. Beitragszusammenführung) :
.

ich möchte euch nun mein fertiges scirpt vorstellen :)

Code:
#!/bin/ksh
# ====================================================================================
# Macht ein File mit TPI-Response Daten vom xxx und schreibt diese in ein File
#
# Dieses Script liest nur die Difftimespalte und vergleicht sie mit einem SollWert,
# wenn dieser überschritten wird, schreibt er eine 1 in ein File, wenn der Wert 5 
# erreicht wurde, alarmiert er via SMS und Email.
#
#                                                       
# ====================================================================================


#Mailing Parameters
MAILLIST="email"
SMSLIST="sms"
#MAILTEXT="`print $myVar` responses needed more than 3 Seconds in the last 2 Minutes, please check the System!"
ERRORTEXT="TPI-Response Time on (`hostname`) needs more than 3 Seconds!"
MAILHEADER="TPI-Response Time"

myVar=`awk ' $1 > 3000 {a++}END{if (a > 5) {print "" ,a,""}} ' testlogfile`;

#Mailtext Definition
MAILTEXT="`print $myVar` responses on (`hostname`) needed more than 3 Seconds in the last 2 Minutes, please check the System!"

if (( $myVar>5 )) ; then
     echo $MAILTEXT | mailx -s "$MAILHEADER" $MAILLIST
     echo $MAILTEXT | mailx -s "$MAILHEADER" $SMSLIST
fi
 
Zuletzt bearbeitet:
Hallo

Geht natürlich auch mit der Brechstange. ;)
Aber das Ding rennt vor die Wand, wenn awk einen fehler produziert, oder myVar leer ist.
Dann evaluiert diese Zeile:
Code:
if (( $myVar>5 )) ...
# zu
if (( >5)) ...

Deshalb bei awk STDERR nach /dev/null und myVar vorher mit einer 0 initialisieren!


Gruß Wolfgang
Übrigens sind die Backticks deprecated, verwende besser diese syntax $(command...)
 
stimmt, vielen dank, habe myvar nun vor awk auf 0 definiert.

kann ich in awk auch noch einen durchschnittswert einbauen, welcher mir auch per sms gschickt wird? dh. testfile mit allen werten durchsuchen, evt alle zusammenzählen und geteilt an anzahl zeilen rechnen oder so?

vielen dank
 

Ähnliche Themen

Server-Monitoring mit RRDTool

Zurück
Oben