Question

J'ai un fichier texte squelette avec des chaînes de caractères génériques:

blah blah blah
blah $PLACEHOLDER_1$
blah
$PLACEHOLDER_2$

et ainsi de suite. Formulaire " spécifique " des espaces réservés n'a pas d'importance - je peux les changer pour ce qui est le plus confortable pour une mise en œuvre spécifique.

J'ai un script bash dans lequel je connais les valeurs pour les espaces réservés et je dois générer un nouveau fichier, les espaces réservés étant remplacés par des valeurs.

#! /bin/sh
PLACEHOLDER_1 = 'string 1'
PLACEHOLDER_2 = 'multiline 
string 
2'
# TODO: Generate file output.txt from file output.template 
#       using placeholders above.

Je peux le faire en plusieurs passes avec sed, mais ce n’est pas amusant. Je ne souhaite pas utiliser Perl. Je veux utiliser textutils et me baser uniquement.

Quel est le meilleur moyen de faire ce que je veux en un seul passage?

Était-ce utile?

La solution

Vous pouvez toujours utiliser sed pour effectuer le remplacement en un seul passage. Il vous suffit de spécifier tous les remplacements en une seule commande.

par exemple.

sed -i 's/PLACEHOLDER_1/string 1/g;s/PLACEHOLDER_2/string 2/g' <file>

Autres conseils

Voici un moyen de le faire sans sed:

Tout d'abord, un fichier de modèle légèrement modifié dans lequel les espaces réservés sont des variables bash:

blah blah blah
blah $PLACEHOLDER_1
blah
$PLACEHOLDER_2

Et le script:

#! /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

Voici une version qui illustre un modèle contenu dans le script, mais avec une torsion. Il présente également les valeurs par défaut, qui peuvent également être utilisées dans la version du fichier de modèle, et vous pouvez également effectuer des opérations mathématiques dans le modèle:

#! /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

Pas de sed, pas de boucles, juste des nids velus et des citations. Je suis sûr que toutes les citations vous protégeront contre les éléments malveillants contenus dans un fichier modèle, mais je ne vais pas vous le garantir.

En vous basant sur la réponse précédente, utilisez peut-être un tableau et calculez la chaîne sed?

#!/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

Semble échouer sur les chaînes multilignes, cependant.

Je ne sais pas comment les tableaux Bash portables pourraient être. Extrait ci-dessus testé avec "GNU bash, version 3.2.17 (1) - release (i386-apple-darwin9.0)"

Ma seule solution bash:

TEMPLATE='
foo
$var1
bar
$var2'
eval "echo \"$TEMPLATE\""

Je suis tombé par hasard sur cette question parce que je cherchais exactement la même chose et que je trouvais envsubst (1) .

Vous pouvez utiliser envsubst si cela ne vous dérange pas d'utiliser des variables d'environnement:

PLACEHOLDER_1='string 1' PLACEHOLDER_2='multiline 
string 
2' envsubst < output.template 

Si vous avez beaucoup de variables, vous pouvez les stocker dans un fichier et simplement source (rappelez-vous d'utiliser export à la fin du fichier recherché!)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top