Füllen Sie Platzhalter in der Datei bei einmaligen Durchgang
Frage
Ich habe eine Skelett Textdatei mit Platzhalter-Zeichenfolge:
blah blah blah
blah $PLACEHOLDER_1$
blah
$PLACEHOLDER_2$
und so weiter. Spezifische „Form“ der Platzhalter spielt keine Rolle -. Ich sie ändern können, was auch immer am bequemsten für spezifische Implementierung
Ich habe einen Bash-Skript, wo ich Werte für Platzhalter wissen, und ich brauche eine neue Datei zu erzeugen, mit Platzhalter durch Werte ersetzt.
#! /bin/sh
PLACEHOLDER_1 = 'string 1'
PLACEHOLDER_2 = 'multiline
string
2'
# TODO: Generate file output.txt from file output.template
# using placeholders above.
ich in mehreren Durchgängen mit sed dies tun können, aber es macht keinen Spaß. Ich nicht wollen Perl verwenden. Ich möchte textutils verwenden und bash selbst nur.
Was ist die beste Art und Weise zu tun, was ich in einem einzigen Durchgang will?
Lösung
Sie können nach wie vor sed verwenden in einem einzigen Durchgang der ersetzen zu tun. Sie müssen nur alle Ersetzungen in einem Befehl angeben.
zB.
sed -i 's/PLACEHOLDER_1/string 1/g;s/PLACEHOLDER_2/string 2/g' <file>
Andere Tipps
Hier ist ein Weg, es zu tun, ohne sed:
Als erstes wird eine leicht modifizierte Template-Datei, in der die Platzhalter sind bash Variablen:
blah blah blah
blah $PLACEHOLDER_1
blah
$PLACEHOLDER_2
Und das Skript:
#! /bin/sh
templatefile=output.template
outputfile=output.txt
PLACEHOLDER_1='string 1'
PLACEHOLDER_2='multiline
string
2'
# DONE: Generate file output.txt from file output.template
# using placeholders above.
echo "$(eval "echo \"$(cat $templatefile)\"")" > $outputfile
Hier ist eine Version, die eine Vorlage im Skript, aber mit einem Twist enthalten demonstriert. Es zeigt auch, Standardwerte, die auch in der Template-Datei-Version verwendet werden können, plus Sie können Mathe in der Vorlage tun:
#! /bin/sh
template='blah blah blah
blah $PLACEHOLDER_1
blah
${PLACEHOLDER_2:-"some text"} blah ${PLACEHOLDER_3:-"some
lines
of
text"} and the total is: $((${VAL_1:-0} + ${VAL_2:-0}))'
# default operands to zero (or 1) to prevent errors due to unset variables
outputfile=output.txt
# gears spin, bells ding, values for placeholders are computed
PLACEHOLDER_1='string 1'
PLACEHOLDER_2='multiline
string
2'
VAL_1=2
VAL_2=4
unset PLACEHOLDER_3 # so we can trigger one of the defaults
# Generate file output.txt from variable $template
# using placeholders above.
echo "$(eval "echo \"$template\"")" > $outputfile
Nein sed, keine Loops, nur haarige Verschachtelung und Zitate. Ich bin mir ziemlich sicher, dass alle zitiert werden Sie von bösartigen Sachen in einer Vorlagendatei schützen, aber ich werde es nicht garantieren.
Basierend auf der vorherige Antwort, vielleicht einen Array verwenden und die Sed Zeichenfolge berechnen?
#!/bin/sh
PLACEHOLDER[0]='string 1'
PLACEHOLDER[1]='multiline
string
2'
s="sed -i "
for(( i=0 ; i<${#PLACEHOLDER[*]} ; i++ )) ; do
echo ${PLACEHOLDER[$i]}
s=$s"s/PLACEHOLDER_$i/${PLACEHOLDER[$i]}/g;"
done
echo $s
Es scheint auf den mehrzeiligen Strings zum Scheitern verurteilt, wenn.
Ich weiß nicht, wie tragbare Bash-Arrays sein könnte. Snippet getestet mit "GNU bash, Version 3.2.17 (1) -release (i386-apple-darwin9.0)"
Meine bash einzige Lösung:
TEMPLATE='
foo
$var1
bar
$var2'
eval "echo \"$TEMPLATE\""
Ich stolperte über diese Frage, weil ich gerade für die exakt gleichen suchen, und ich fand envsubst(1)
.
Sie können mit envsubst , wenn Sie nicht mit Umgebungsvariablen nichts dagegen:
PLACEHOLDER_1='string 1' PLACEHOLDER_2='multiline
string
2' envsubst < output.template
Wenn Sie eine Menge von Variablen haben Sie sie in einer Datei speichern und source
es gerade (nicht vergessen export
am Ende der Quellen-Datei zu verwenden!)