Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Variablen in einer externen Datei ausfüllen

12 views
Skip to first unread message

Horst Felder

unread,
Apr 9, 2012, 4:27:56 AM4/9/12
to
Hallo!

Ich habe in einem Script mehrere Variablen gesetzt, beispielsweise
kellert=`echo $zeile | awk -F';' '{print $8}'`
gartent=`echo $zeile | awk -F';' '{print $20}'`

und möchte jetzt die gefüllten Variablen in einer externen Textdatei
(kein Script, sondern html) wieder einsetzen, beispielsweise in
Kellertemperatur = $kellert° Grad
Gartentemperatur = $gartent° Grad

Wie rufe ich die externe Textdatei im Script auf und wie übergebe
ich die Variablen?

--
Mit freundlichen Grüßen
Horst Felder - www.flohheim.de
GNU/Linux; damit ich auch morgen noch vernünftig arbeiten kann!

Helmut Hullen

unread,
Apr 9, 2012, 5:29:00 AM4/9/12
to
Hallo, Horst,

Du meintest am 09.04.12:

> Ich habe in einem Script mehrere Variablen gesetzt, beispielsweise
> kellert=`echo $zeile | awk -F';' '{print $8}'`
> gartent=`echo $zeile | awk -F';' '{print $20}'`

> und möchte jetzt die gefüllten Variablen in einer externen Textdatei
> (kein Script, sondern html) wieder einsetzen, beispielsweise in
> Kellertemperatur = $kellert° Grad
> Gartentemperatur = $gartent° Grad

> Wie rufe ich die externe Textdatei im Script auf und wie übergebe
> ich die Variablen?

Da gibt es viele Möglichkeiten.

Mein Favorit (ungetestet):

Datei=meine_HTML_Datei
test -s $Datei && {
ed -s $Datei <<EOF
/^Kellertemperatur/
c
Kellertemperatur= ${kellert}° Grad
.
wq
EOF

ed -s $Datei <<EOF
/^Gartentemperatur/
c
Gartentemperatur= ${gartent}° Grad
.
wq
EOF
}

# -------------------

Das ginge "im Prinzip" auch mit "sed" (insbesondere "sed -i").

Ebenfalls ungetestet, Kurzform:

Datei=meine_HTML_Datei
test -s $Datei && {
sed -i "s/^Kellertemperatur*/Kellertemperatur= ${kellert}° Grad/"
sed -i "s/^Gartentemperatur*/Gartentemperatur= ${gartent}° Grad/"
}

Viele Gruesse
Helmut

"Ubuntu" - an African word, meaning "Slackware is too hard for me".

Cyrus Kriticos

unread,
Apr 9, 2012, 7:19:42 AM4/9/12
to
On 04/09/2012 10:27 AM, Horst Felder wrote:
> Ich habe in einem Script mehrere Variablen gesetzt, beispielsweise
> kellert=`echo $zeile | awk -F';' '{print $8}'`
> gartent=`echo $zeile | awk -F';' '{print $20}'`
>
> und möchte jetzt die gefüllten Variablen in einer externen Textdatei
> (kein Script, sondern html) wieder einsetzen, beispielsweise in
> Kellertemperatur = $kellert° Grad
> Gartentemperatur = $gartent° Grad
>
> Wie rufe ich die externe Textdatei im Script auf und wie übergebe
> ich die Variablen?

Ich würde es mit sowas versuchen:

while read X; do eval echo "$X"; done <vorlage.html >output.html

--
Grüße | NDR-Beitrag ueber MCR Geldschrank Vertriebsgesellschaft Berlin
Cyrus | http://www.lachschon.de/item/64671-kuchenblechmafia/

Cyrus Kriticos

unread,
Apr 9, 2012, 7:28:03 AM4/9/12
to
On 04/09/2012 01:19 PM, Cyrus Kriticos wrote:
>
> Ich würde es mit sowas versuchen:
>
> while read X; do eval echo "$X"; done <vorlage.html >output.html

Denkfehler auf meiner Seite, funktioniert leider nicht.

Bernd Hohmann

unread,
Apr 9, 2012, 7:48:12 AM4/9/12
to
Am 09.04.2012 10:27, schrieb Horst Felder:

> Ich habe in einem Script mehrere Variablen gesetzt, beispielsweise
> kellert=`echo $zeile | awk -F';' '{print $8}'`
> gartent=`echo $zeile | awk -F';' '{print $20}'`
>
> und möchte jetzt die gefüllten Variablen in einer externen Textdatei
> (kein Script, sondern html) wieder einsetzen, beispielsweise in
> Kellertemperatur = $kellert° Grad
> Gartentemperatur = $gartent° Grad
>
> Wie rufe ich die externe Textdatei im Script auf und wie übergebe
> ich die Variablen?

replace (kommt aus dem MySQL Utilities):

replace '$kellert' $kellert '$gartent' $gartent -- temperatur.html

Obacht: temperatur.html wird überschrieben, also am besten eine
"temperatur.tpl" erstellen und vorher nach temperatur.html umkopieren.

Bernd

Bernd Hohmann

unread,
Apr 9, 2012, 7:55:53 AM4/9/12
to
Am 09.04.2012 13:48, schrieb Bernd Hohmann:

> replace (kommt aus dem MySQL Utilities):

Und da wäre noch standalone "replaceit", geht genauso:

replaceit --input=temperatur.html '$kellert' $kellert

Bernd

Ulli Horlacher

unread,
Apr 10, 2012, 2:29:01 AM4/10/12
to
Muss beides normalerweise nachinstalliert werden, waehrend perl eigentlich
immer schon da ist:

perl -p -i -e 's/\$kellert/$ENV{kellert}/g' *.html


--
Ullrich Horlacher Informationssysteme und Serverbetrieb
Rechenzentrum E-Mail: horl...@rus.uni-stuttgart.de
Universitaet Stuttgart Tel: ++49-711-685-65868
Allmandring 30 Fax: ++49-711-682357
70550 Stuttgart (Germany) WWW: http://www.rus.uni-stuttgart.de/

Horst Felder

unread,
Apr 10, 2012, 4:18:30 AM4/10/12
to
Hallo Bernd!

Bernd Hohmann <bernd.hohma...@freihaendler.com> schrieb:
> replace (kommt aus dem MySQL Utilities):
>
> replace '$kellert' $kellert '$gartent' $gartent -- temperatur.html

Vielen Dank! Habe mich für diese Variante entschieden, da es
ein Einzeiler ist und "replace" in meiner Standardinstallation drin
ist...

Ich bedanke mich auch bei allen anderen für ihre Hilfe (immer wieder
interessant wie viele Lösungsmöglichkeiten und Ansätze es für
ein Problem gibt)!

Einen schönen Tag noch!

> Bernd

Thomas 'PointedEars' Lahn

unread,
Apr 17, 2012, 1:19:48 AM4/17/12
to
Horst Felder wrote:

> Hallo Bernd!

Isch 'eise abär gar nischd Bernd, signor.

> Bernd Hohmann <bernd.hohma...@freihaendler.com> schrieb:
>> replace (kommt aus dem MySQL Utilities):
>>
>> replace '$kellert' $kellert '$gartent' $gartent -- temperatur.html
>
> Vielen Dank! Habe mich für diese Variante entschieden, da es
> ein Einzeiler ist und "replace" in meiner Standardinstallation drin
> ist...

Diese Lösung funktioniert natürlich _nicht_ (zuverlässig), denn wenn der
Variablenwert Leerzeichen, Tabulaturzeichen oder Zeilenumbrüche enthält,
dann wird das dem Leerzeichen folgende Wort als eigener Parameter für
replace(1) expandiert (per Default ist IFS=$' \t\n'). Im schlimmsten Fall
werden so mit

kellert="foo bar"
gartent="baz bla"
replace '$kellert' $kellert '$gartent' $gartent -- temperatur

sämtliche Vorkommen von `$kellert' durch `foo', von `bar' durch `$gartent'
und von `baz' durch `bla' ersetzt, und es gäbe nicht einmal eine
Fehlermeldung von replace(1), da Obiges äquivalent ist zu

replace '$kellert' 'foo' 'bar' '$gartent' 'baz' 'bla' -- temperatur

(Leerzeichen zur Verdeutlichung eingefügt). Korrekt wäre daher

replace '$kellert' "$kellert" '$gartent' "$gartent" -- temperatur

Allerdings gibt es in einer GNU-Standardinstallation wie der Deinigen¹ und
vermutlich in allen Unices (da in POSIX spezifiziert) zum Ersetzen von
Strings in der Eingabe oder in Dateien bereits das Tool sed(1) (Stream
Editor) aus den textutils. Zu Obigem äquivalent wäre daher

sed -ie '
s/\$kellert/'"$kellert"'/g;
s/\$gartent/'"$gartent"'/g
' temperatur

Jedoch ist hier zu beachten, dass der Variablenwert keine speziellen
Sequenzen wie etwa `\0' enthalten darf, da sonst dieser expandiert wird.
Umgekehrt kann man sich das natürlich auch zunutze machen, um z. B. an
Wörter bestimmte Zeichenfolgen anzuhängen:

bar='\0baz'
sed -e 's/foo/'"$bar"'/g'

hängt an alle `foo's `baz' an.

Mit GNU awk(1) – welches Du bereits benutzt hast – ist ebenfalls Ersetzung
möglich. Da man in der Shell nicht die Datei überschreiben kann, die man
gerade liest, kann man entweder mit einer temporären Datei arbeiten, oder
(wie im Beispiel) den originalen Datei-Inhalt in einer Variablen speichern
(siehe `man bash', Abschnitt "Command Substitution" und natürlich `man
awk'):

# save file content in variable
content=$(cat temperatur)

# replace template variables
content=$(printf '%s' "$content" |
awk -v "kellert=$kellert" -v "gartent=$gartent" '
{
gsub("\\$kellert", kellert, $0);
gsub("\\$gartent", gartent, $0);
print;
}
')

# update file
printf '%s' "$content" > temperatur

Ausserdem beherrscht die GNU bash spätestens seit Version 4.1-alpha
ebenfalls die unbedingte globale Textersetzung [1] (von der KornShell
übernommen [2]), so dass Du mit

content=$(cat temperatur)
content=${content//'$kellert'/$kellert}
content=${content//'$gartent'/$gartent}
printf '%s' "$content" > temperatur

– von cat abgesehen – ganz ohne weitere Tools und ohne Escaping auskommst
(siehe `man bash', Abschnitt "Parameter Expansion"). (Die Ersetzung mit
einer Schleife zu automatisieren ist mir noch nicht gelungen, da bash
${$var} nicht akzeptiert. Ideen?)

Schliesslich geht es – weniger performant als Obiges, dafür aber weniger
anfällig für Stringlängenbegrenzung – auch noch ohne cat(1):

printf '%s' "$(
IFS='' while read -r line
do
line=${line//'$kellert'/$kellert}
line=${line//'$gartent'/$gartent}
printf '%s\n' "$line"
done < temperatur
)" > temperatur

Weil die Schleife in einer Subshell ausgeführt wird, bevor die schreibende
Umleitung stattfindet, sollte es hier keine Race Condition geben (zuerst
muss das Ergebnis der Command Substitution ermittelt werden). In GNU bash,
version 4.2.20(1)-release (i486-pc-linux-gnu) funktioniert das jedenfalls.

[Weshalb IFS=''? `read' ist zum Einlesen tabellarischer Daten gedacht. Es
muss daher verhindert werden, dass Leerzeichen am Anfang ignoriert werden.
Durch Setzen des internen Feldtrenners (Internal Field Separator) auf die
leere Zeichenfolge wird die gesamte Zeile als ein Feld betrachtet und in
`line' gespeichert. (Mit `-r' wird ausserdem verhindert, dass `\' in der
Zeile als Escape-Zeichen interpretiert wird.)

Weshalb printf(1) und nicht echo(1)? echo(1) gibt immer einen Zeilenumbruch
am Ende aus und `echo -n' – was das verhindert – ist *nicht portabel*
(schlimmstenfalls wird `-n' mit ausgegeben). printf(1) hängt hingegen
nichts an und ist immer portabel; es ist in POSIX spezifiziert und gehört
auch zur GNU-Standardinstallation.

Weshalb nicht einfacher `printf "$content"'? Der Wert von `content' könnte
`%…' enthalten und es gibt keinen Parameter, um das zu expandieren. printf
'%s' gibt _nichts_ aus.]

_______
¹ siehe Headerfeld `X-Newsreader'

[1] <http://tiswww.case.edu/php/chet/bash/CHANGES>
[2] <http://www2.research.att.com/sw/download/man/man1/ksh.html>
--
PointedEars

Please do not Cc: me. / Bitte keine Kopien per E-Mail.
0 new messages