MySQL-Abfrage an Variable übergeben

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
mojorianer
Beiträge: 10
Registriert: 16.03.2011 16:57:13

MySQL-Abfrage an Variable übergeben

Beitrag von mojorianer » 16.03.2011 17:08:40

Hallo,

ich möchte die Ausgabe einer MySQL-Anfrage zeilenweise auswerten und die darin enthaltenen Werte in ein Template schreiben und gegen bestimmte Platzhalter austauschen.
Mein Problem ist, dass ich die Werte aus der Anfrage nicht richtig in verschiedene Variablen bekomme.

Das Template /root/template

Code: Alles auswählen

Host: platzhalter1
Service: platzhalter2
Zeit: platzhalter3
Und das Bash-Skript

Code: Alles auswählen

#!/bin/bash

mysql -uroot -pGeheim otrs < /root/query

while read line   
do   
    echo $line | awk -F\| '{print $1,$2,$3}'
	sed -e 's/platzhalter1/$1/g' -e 's/platzhalter2/$2/g' -e 's/platzhalter3/$3/g' /root/template > /root/temp1

done < /tmp/ergebnis
MySQL Abfrage /root/ergebnis

Code: Alles auswählen

wertX|wertY|wertZ
wertA|wertB|wertC
Im File /root/temp1 steht nach dem Ausführen immer $1,$2 bzw. $3 und nicht der Inhalt dieser Variablen.
Ich denke mal awk und sed sind im Skript nicht richtig verknüpft.

Vielleicht hat einer einen Vorschlag.

Vielen Dank

nepos
Beiträge: 5238
Registriert: 05.01.2005 10:08:12

Re: MySQL-Abfrage an Variable übergeben

Beitrag von nepos » 16.03.2011 17:14:35

Dein Fehler sind die Single Quotes um die sed-Kommandos. Dadurch werden die Variablen nicht vorher durch die Shell expandiert.
Probiers mal mit Double Quotes, damit sollte es dann eigentlich klappen.

mojorianer
Beiträge: 10
Registriert: 16.03.2011 16:57:13

Re: MySQL-Abfrage an Variable übergeben

Beitrag von mojorianer » 16.03.2011 17:49:57

Hy,

die Platzhalter1 bis 3 werden dann einfach gelöscht und die Felder bleiben leer.

Gruß

Mojo

newdeb
Beiträge: 134
Registriert: 03.02.2011 11:11:21
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Frankfurt

Re: MySQL-Abfrage an Variable übergeben

Beitrag von newdeb » 16.03.2011 19:18:17

Die awk-Feldvariablen $1,$2,... haben nichts mit den Positionsparametern $1, $2, ... der Shell zu tun.
Die Shell-Positionsparameter kann man aber mit "set" explizit zuweisen. Das awk-Statement wird einfach in eine Kommandosubstitution $() verpackt:

Code: Alles auswählen

while read line   
do   
   set -- $(echo $line | awk -F\| '{print $1,$2,$3}')
   sed -e "s/platzhalter1/$1/g" -e "s/platzhalter2/$2/g" -e "s/platzhalter3/$3/g" /root/template >> /root/temp1

done < /tmp/ergebnis

mojorianer
Beiträge: 10
Registriert: 16.03.2011 16:57:13

Re: MySQL-Abfrage an Variable übergeben

Beitrag von mojorianer » 16.03.2011 20:27:37

Super :D Es läuft.

Das Skript versendet jetzt pro Zeile aus der MySQL Anfrage einen Bericht per Mail.

Code: Alles auswählen

#!/bin/bash

mysql -uroot -pGeheim otrs < /root/script/query

while read line   
do  
	set -- $(echo $line | awk -F\| '{print $1,$2,$3}')
	sed -e "s/platz1/$1/g" -e "s/platz2/$2/g" -e "s/platz3/$3/g" /root/script/template > /root/script/temp1.txt
	cat /root/script/empty | mutt user@mail.de -a /root/script/temp1.txt -s "Report from Host: $1" && rm /root/script/temp1.txt
done < /tmp/query-result 
Vielen vielen Dank

Mojo

mojorianer
Beiträge: 10
Registriert: 16.03.2011 16:57:13

Re: MySQL-Abfrage an Variable übergeben

Beitrag von mojorianer » 17.03.2011 01:34:26

Leider läuft es doch noch nicht richtig.

Hier noch mal das vollständige Skript

Code: Alles auswählen

#!/bin/bash

mysql -uroot -pGeheim otrs < /root/script/query

while read line   
do  
	set -- $(echo $line | awk -F\| '{print $1,$2,$3,$4,$5}')
	sed -e "s/platz1/$1/g" -e "s/platz2/$2/g" -e "s/platz3/$3/g" -e "s/platz4/$4/g" -e "s/platz5/$5/g" /root/script/template >> /root/script/test1.txt
	cat /root/script/empty | mutt user@mail.de -a /root/script/test1.txt -s "Report from Host: $1" && rm /root/script/test1.txt
done < /tmp/query-result 
rm /tmp/query-result
/root/script/template

Code: Alles auswählen

Host: platz1
Service: platz2
Start: platz3
Ende: platz4
Dauer: platz5
/tmp/query-result

Code: Alles auswählen

NAC-Server|Packetfence-Services-PF|2011-03-14 21:07:01|2011-03-14 21:12:41|540.000000
Zwischen Datum und Uhrzeit sind keine Pipes sondern Leerzeichen!

/root/scripts/test1.txt sieht dannach so aus

Code: Alles auswählen

Host: NAC-Server
Service: Packetfence-Services-PF
Start: 2011-03-14
Ende: 21:07:01
Dauer: 2011-03-14
Wenn ich zur Überprüfung folgendes ausführe

Code: Alles auswählen

cat /tmp/query-result | awk -F[\|] '{print $3}'
wird korrekt an der Pipe getrennt.

Code: Alles auswählen

2011-03-14 21:07:01
Vielen Dank

newdeb
Beiträge: 134
Registriert: 03.02.2011 11:11:21
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Frankfurt

Re: MySQL-Abfrage an Variable übergeben

Beitrag von newdeb » 17.03.2011 09:35:02

set weist Datum und Uhrzeit separaten Positionsvariablen zu:
awk $3 --> Shell $3, $4 (Start-Datum und -uhrzeit)
awk $4 --> Shell $5, $6 (Ende-Datum und -uhrzeit)
awk $5 --> Shell $7 (Dauer)

Ich würde einfach das sed-Statement entsprechend anpassen, also etwa so:

Code: Alles auswählen

sed -e "s/platz1/$1/g" -e "s/platz2/$2/g" -e "s/platz3/$3 $4/g" -e "s/platz4/$5 $6/g" -e "s/platz5/$7/g" /root/script/template

rendegast
Beiträge: 15041
Registriert: 27.02.2006 16:50:33
Lizenz eigener Beiträge: MIT Lizenz

Re: MySQL-Abfrage an Variable übergeben

Beitrag von rendegast » 17.03.2011 14:25:52

Ich habe noch eine Array-Variante,
mit einer übersichtlicheren Version des sed-Statements:

Code: Alles auswählen

while read line   
do   
    WERT=( $(echo $line | awk -F\| '{print $1,$2,$3}') )
   #echo A1 ${WERT[0]} A2 ${WERT[1]} A3 ${WERT[2]}

   #sed -e 's/platzhalter1/$1/g' -e 's/platzhalter2/$2/g' -e 's/platzhalter3/$3/g' /root/template > /root/temp1
   #sed -e "s/platz1/${WERT[0]}/g;s/platz2/${WERT[1]}/g;s/platz3/${WERT[2]}/g" /tmp/template > /tmp/temp1
   sed -e "
    s/platz1/${WERT[0]}/g
    s/platz2/${WERT[1]}/g
    s/platz3/${WERT[2]}/g
    " /tmp/template > /tmp/temp1

cat /tmp/temp1

done < /tmp/ergebnis



Wegen der Leerzeichen in den Zeiten,
statt diese als 2 Variablen in sed zusammenzufassen (eine Art Walkaround),
könnte nicht awk direkt eine Array-Variable zuweisen

Code: Alles auswählen

while read line   
do   
    #WERT:
    echo $line | awk -F\| '{ WERT[0]=$1 WERT[1]=$2 ....}'
und den Array direkt im Template verwursten:

Code: Alles auswählen

Host: ${WERT[0]}
Service: ${WERT[1]}
Zeit: ${WERT[2]}
Ende: ${WERT[3]}
Dauer: ${WERT[4]}
?

Eigentlich sieht das sehr einfach aus, ganz ohne sed:

Code: Alles auswählen

    echo $line | awk -F\|  -f /tmp/template.awk
/tmp/template.awk:

Code: Alles auswählen

{
print "Host:",$1
print "Service:",$2
print "Zeit:",$3
print "Ende:",$4
print "Dauer:",$5
}
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")

mojorianer
Beiträge: 10
Registriert: 16.03.2011 16:57:13

Re: MySQL-Abfrage an Variable übergeben

Beitrag von mojorianer » 17.03.2011 18:24:50

Hallo,

ich habe mich für diese Variante entschieden.

Code: Alles auswählen

    sed -e "s/platz1/$1/g" -e "s/platz2/$2/g" -e "s/platz3/$3 $4/g" -e "s/platz4/$5 $6/g" -e "s/platz5/$7/g" /root/script/template
Nachdem ich noch mal alles geprüft habe, ist mir aufgefallen, dass ich unter Umständen im 2. Feld ($2), abhängig der MySQL-Anfrage, auch ein Leerzeichen habe.
Das Skript ist somit nicht wirklich wasserdicht.

Dieser Versuch:
Wegen der Leerzeichen in den Zeiten,
statt diese als 2 Variablen in sed zusammenzufassen (eine Art Walkaround),
könnte nicht awk direkt eine Array-Variable zuweisen

Code: Alles auswählen
while read line
do
#WERT:
echo $line | awk -F\| '{ WERT[0]=$1 WERT[1]=$2 ....}'

und den Array direkt im Template verwursten:

Code: Alles auswählen
Host: ${WERT[0]}
Service: ${WERT[1]}
Zeit: ${WERT[2]}
Ende: ${WERT[3]}
Dauer: ${WERT[4]}
gibt folgende Fehler:

Code: Alles auswählen

awk: {WERT[0]=$1 WERT[1]=$2 WERT[2]=$3 WERT[3]=$4 WERT[4]=$5}
awk:                    ^ syntax error
Eine Idee?

Danke

newdeb
Beiträge: 134
Registriert: 03.02.2011 11:11:21
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Frankfurt

Re: MySQL-Abfrage an Variable übergeben

Beitrag von newdeb » 17.03.2011 19:01:12

Der letzte Lösungsvorschlag von rendegast (Feldvariablen $1,$2,.. direkt verwendet in template.awk) sollte eigentlich funktionieren.
Eine reine sed-Lösung ist natürlich auch möglich:

Code: Alles auswählen

while IFS='|' read host service start ende dauer   
do   
   sed -e "s/platz1/$host/"    \
       -e "s/platz2/$service/" \
       -e "s/platz3/$start/"   \
       -e "s/platz4/$ende/"    \
       -e "s/platz5/$dauer/" /root/script/template
Die Zuweisung IFS='|' gilt temporär nur für die read-Anweisung, man umgeht damit das Leerzeichen-Problem.

rendegast
Beiträge: 15041
Registriert: 27.02.2006 16:50:33
Lizenz eigener Beiträge: MIT Lizenz

Re: MySQL-Abfrage an Variable übergeben

Beitrag von rendegast » 17.03.2011 19:04:01

Richtig, war eine Idee/Richtung,
ausgearbeitet so, da die awk-Werte ja selbst schon einen array bilden:
rendegast hat geschrieben: Eigentlich sieht das sehr einfach aus, ganz ohne sed:

Code: Alles auswählen

        echo $line | awk -F\|  -f /tmp/template.awk
/tmp/template.awk:

Code: Alles auswählen

    {
    print "Host:",$1
    print "Service:",$2
    print "Zeit:",$3
    print "Ende:",$4
    print "Dauer:",$5
    }
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")

mojorianer
Beiträge: 10
Registriert: 16.03.2011 16:57:13

Re: MySQL-Abfrage an Variable übergeben

Beitrag von mojorianer » 17.03.2011 20:36:04

Danke.

Hat funktioniert.

Ich habe mich für die sed-Lösung entschieden.

LG

Antworten