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?

War es hilfreich?

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!)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top