Comment remplacer les espaces réservés $ {} dans un fichier texte?

164

Je veux diriger la sortie d'un fichier "modèle" dans MySQL, le fichier ayant des variables comme ${dbName}intercalées. Quel est l'utilitaire de ligne de commande pour remplacer ces instances et vider la sortie sur la sortie standard?

Dana le Sane
la source

Réponses:

192

Sed !

Template.txt donné:

Le nombre est $ {i}
Le mot est $ {word}

il suffit de dire:

sed -e "s/\${i}/1/" -e "s/\${word}/dog/" template.txt

Merci à Jonathan Leffler pour l'astuce de passer plusieurs -earguments à la même sedinvocation.

utilisateur
la source
13
Vous pouvez combiner ces deux commandes sed en une seule: sed -e "s / \ $ {i} / 1 /" -e "s / \ $ {word} / dog /"; c'est plus efficace. Vous pouvez rencontrer des problèmes avec certaines versions de sed à peut-être 100 opérations de ce type (problème d'il y a des années - peut-être pas toujours vrai, mais méfiez-vous de HP-UX).
Jonathan Leffler
1
Merci Jonathan, exactement ce que je cherchais.
Dana the Sane
3
Petit conseil: si "1" ou "chien" dans l'exemple donné contenait un symbole dollar, vous devrez l'échapper avec une barre oblique inverse (sinon le remplacement ne se produira pas).
MatthieuP
9
Vous n'avez pas non plus besoin du cat. Tout ce dont vous avez besoin est sed -e "s/\${i}/1/" -e "s/\${word}/dog/" template.text.
HardlyKnowEm
3
Que faire si le texte de remplacement est un mot de passe? Dans ce cas, sedattendra un texte échappé, ce qui est un problème.
jpbochi
179

Mettre à jour

Voici une solution de yottatsa sur une question similaire qui ne remplace que des variables comme $ VAR ou $ {VAR}, et est un bref one-liner

i=32 word=foo envsubst < template.txt

Bien sûr, si je et le mot sont dans votre environnement, alors c'est juste

envsubst < template.txt

Sur mon Mac, il semble qu'il a été installé dans le cadre de gettext et de MacGPG2

Ancienne réponse

Voici une amélioration de la solution de mogsie sur une question similaire, ma solution ne vous oblige pas à escaler des guillemets doubles, c'est le cas de mogsie, mais la sienne est une ligne!

eval "cat <<EOF
$(<template.txt)
EOF
" 2> /dev/null

La puissance de ces deux solutions est que vous n'obtenez que quelques types d'extensions de shell qui ne se produisent pas normalement $ ((...)), `...` et $ (...), bien que la barre oblique inverse soit une caractère d'échappement ici, mais vous n'avez pas à vous soucier du fait que l'analyse a un bogue, et il fait très bien plusieurs lignes.

plockc
la source
6
Je trouve que le nu envsubstne fonctionne pas si vos envars ne sont pas exportés.
Toddius Zho
4
@ToddiusZho: Il n'y a pas de variable d'environnement qui ne soit pas exportée - c'est précisément l'exportation qui fait d'une variable shell une variable d'environnement. envsubst, comme son nom l'indique, ne reconnaît que les variables d' environnement , pas les variables shell . Il convient également de noter qu'il envsubsts'agit d'un utilitaire GNU , et donc non préinstallé ou disponible sur toutes les plates-formes.
mklement0
2
Peut-être qu'une autre façon de dire est que envsubst ne voit que ses propres variables d'environnement de processus, donc les variables shell "normales" que vous auriez pu définir plus tôt (sur des lignes séparées) ne sont pas héritées par les processus enfants à moins que vous ne les "exportiez". Dans mon exemple d'utilisation de gettext ci-dessus, je modifie l'environnement gettext hérité via un mécanisme bash en les préfixant à la commande que je suis sur le point d'exécuter
plockc
1
J'ai une chaîne avec $ HOME dedans, j'ai trouvé que $ HOME fonctionnait comme shell par défaut, à la place de $ HOME comme mon propre / home / zw963, mais, il semble ne pas prendre en charge la substitution $ (cat / etc / hostname), donc il ne correspond pas complètement à ma propre demande.
zw963 le
3
Merci pour la "vieille réponse", car elle autorise non seulement les variables, mais aussi des commandes shell comme $ (ls -l)
Alek
46

Utilisez /bin/sh. Créez un petit script shell qui définit les variables, puis analysez le modèle à l'aide du shell lui-même. Comme ça (modifier pour gérer correctement les nouvelles lignes):

Fichier template.txt:

the number is ${i}
the word is ${word}

Fichier script.sh:

#!/bin/sh

#Set variables
i=1
word="dog"

#Read in template one line at the time, and replace variables (more
#natural (and efficient) way, thanks to Jonathan Leffler).
while read line
do
    eval echo "$line"
done < "./template.txt"

Production:

#sh script.sh
the number is 1
the word is dog
gnud
la source
2
Pourquoi pas simplement: while read line; faire eval echo "$ line"; fait <./template.txt ??? Il n'est pas nécessaire de lire le fichier entier en mémoire, mais de le cracher une ligne à la fois via une utilisation intensive de la tête et de la queue. Mais «eval» est OK - à moins que le modèle ne contienne des caractères shell comme des guillemets.
Jonathan Leffler
16
C'est très dangereux! Toutes les bashcommandes de l'entrée seront exécutées. Si le modèle est: "les mots sont; rm -rf $ HOME" vous perdrez des fichiers.
rzymek
1
@rzymek - rappelez-vous, il veut diriger ce fichier directement vers la base de données. Donc, apparemment, l'entrée est approuvée.
gnud
4
@gnud Il y a une différence entre faire suffisamment confiance à un fichier pour stocker son contenu et lui faire suffisamment confiance pour exécuter tout ce qu'il contient.
Mark
3
Pour noter les contraintes: (a) les guillemets doubles dans l'entrée sont discrètement ignorés, (b) la readcommande, telle qu'elle est écrite, supprime les espaces de début et de fin de chaque ligne et `` mange '' les \ caractères., (C) ne l'utilise que si vous faites confiance ou contrôlez l'entrée, car les substitutions de commandes ( `…` ou $(…)) intégrées dans l'entrée permettent l'exécution de commandes arbitraires en raison de l'utilisation de eval. Enfin, il y a une petite chance que echole début d'une ligne soit confondu avec l'une de ses options de ligne de commande.
mklement0
23

J'y réfléchissais à nouveau, compte tenu de l'intérêt récent, et je pense que l'outil auquel je pensais à l'origine était m4le processeur de macros pour les outils automatiques. Donc, au lieu de la variable que j'ai spécifiée à l'origine, vous utiliseriez:

$echo 'I am a DBNAME' | m4 -DDBNAME="database name"
Dana le Sane
la source
1
Cette solution présente le moins d'inconvénients des réponses ici. Connaissez-vous un moyen de remplacer $ {DBNAME} au lieu de seulement DBNAME?
Jack Davidson
@JackDavidson J'utiliserais envsubstpour cette simple utilisation de remplacement de variable / modèle, comme mentionné dans d'autres réponses. m4est un excellent outil, mais c'est un préprocesseur complet avec beaucoup plus de fonctionnalités et donc une complexité qui peut ne pas être nécessaire si vous souhaitez simplement remplacer certaines variables.
imiric le
13

template.txt

Variable 1 value: ${var1}
Variable 2 value: ${var2}

data.sh

#!/usr/bin/env bash
declare var1="value 1"
declare var2="value 2"

parser.sh

#!/usr/bin/env bash

# args
declare file_data=$1
declare file_input=$2
declare file_output=$3

source $file_data
eval "echo \"$(< $file_input)\"" > $file_output

./parser.sh data.sh template.txt parsed_file.txt

parsed_file.txt

Variable 1 value: value 1
Variable 2 value: value 2
ChaPuZ
la source
1
Comme cela a été noté ailleurs: n'utilisez ceci que si vous faites entièrement confiance ou contrôlez l'entrée, car les substitutions de commandes ( `…` ou $(…)) intégrées dans l'entrée permettent l'exécution de commandes arbitraires en raison de l'utilisation de eval, et l'exécution directe du code shell en raison de l'utilisation de source. De plus, les guillemets doubles dans l'entrée sont discrètement ignorés et echopeuvent confondre le début d'une ligne avec l'une de ses options de ligne de commande.
mklement0
Malheureusement, cela supprime tous les guillemets doubles (") du fichier de résultat. Existe-t-il un moyen de faire de même sans supprimer les guillemets doubles?
Ivaylo Slavov
J'ai trouvé ce que je cherchais ici: stackoverflow.com/a/11050943/795158 ; J'ai utilisé envsubst. La différence est que les vars doivent être exportées, ce qui me convenait.
Ivaylo Slavov
si le fichier texte contient "" "ou". " , la substance échouera.
shuiqiang
12

Voici une fonction Bash robuste qui, malgré l'utilisationeval , devrait être sûre à utiliser.

Tout ${varName} les références de variable dans le texte d'entrée sont développées en fonction des variables du shell appelant.

Rien d'autre n'est développé: ni les références de variables dont les noms ne sont pas inclus dans {...}(comme $varName), ni les substitutions de commandes ( $(...)et la syntaxe héritée `...`), ni les substitutions arithmétiques ( $((...))et la syntaxe héritée$[...] ).

Pour traiter a $comme un littéral, \-escape it; par exemple:\${HOME}

Notez que l'entrée n'est acceptée que via stdin .

Exemple:

$ expandVarsStrict <<<'$HOME is "${HOME}"; `date` and \$(ls)' # only ${HOME} is expanded
$HOME is "/Users/jdoe"; `date` and $(ls)

Code source de la fonction:

expandVarsStrict(){
  local line lineEscaped
  while IFS= read -r line || [[ -n $line ]]; do  # the `||` clause ensures that the last line is read even if it doesn't end with \n
    # Escape ALL chars. that could trigger an expansion..
    IFS= read -r -d '' lineEscaped < <(printf %s "$line" | tr '`([$' '\1\2\3\4')
    # ... then selectively reenable ${ references
    lineEscaped=${lineEscaped//$'\4'{/\${}
    # Finally, escape embedded double quotes to preserve them.
    lineEscaped=${lineEscaped//\"/\\\"}
    eval "printf '%s\n' \"$lineEscaped\"" | tr '\1\2\3\4' '`([$'
  done
}

La fonction suppose qu'aucun 0x1, 0x2, 0x3, et les 0x4caractères de contrôle sont présents dans l'entrée, parce que ces caractères. sont utilisés en interne - puisque la fonction traite du texte , cela devrait être une hypothèse sûre.

mklement0
la source
2
C'est l'une des meilleures réponses ici. Même avec l'utilisation, evalil est assez sûr à utiliser.
anubhava le
1
Cette solution fonctionne avec les fichiers JSON! (s'échapper "correctement!)
WBAR
2
Une bonne chose avec cette solution est qu'elle vous permettra de fournir des valeurs par défaut pour les variables manquantes ${FOO:-bar}ou de ne sortir quelque chose que si elle est définie - ${HOME+Home is ${HOME}}. Je soupçonne qu'avec une petite extension, il pourrait également renvoyer des codes de sortie pour les variables manquantes, ${FOO?Foo is missing}mais tldp.org/LDP/abs/html/parameter-substitution.html n'a pas actuellement une liste de ceux-ci si cela aide
Stuart Moore
11

Créer rendertemplate.sh:

#!/usr/bin/env bash

eval "echo \"$(cat $1)\""

Et template.tmpl:

Hello, ${WORLD}
Goodbye, ${CHEESE}

Rendre le modèle:

$ export WORLD=Foo
$ CHEESE=Bar ./rendertemplate.sh template.tmpl 
Hello, Foo
Goodbye, Bar
neu242
la source
2
Cela
supprime les
Essayé: eval "echo $ (cat $ 1)" - sans guillemets, et cela a fonctionné pour moi.
access_granted
2
Du point de vue de la sécurité, ce sont de mauvaises nouvelles. Si votre modèle contient $(rm -rf ~), vous l'exécutez sous forme de code.
Charles Duffy
eval "echo \"$(cat $1)\"" Fonctionne très bien !
dev devv
10

voici ma solution avec perl basée sur l'ancienne réponse, remplace les variables d'environnement:

perl -p -e 's/\$\{(\w+)\}/(exists $ENV{$1}?$ENV{$1}:"missing variable $1")/eg' < infile > outfile
Thomas
la source
2
C'est bien. Vous n'avez pas toujours perl, mais quand vous le faites, c'est simple et direct.
Aaron McMillin le
5

Si vous êtes prêt à utiliser Perl , ce serait ma suggestion. Bien qu'il existe probablement des experts sed et / ou AWK qui savent probablement comment faire cela beaucoup plus facilement. Si vous avez un mappage plus complexe avec plus que dbName pour vos remplacements, vous pouvez l'étendre assez facilement, mais vous pouvez tout aussi bien le mettre dans un script Perl standard à ce stade.

perl -p -e 's/\$\{dbName\}/testdb/s' yourfile | mysql

Un court script Perl pour faire quelque chose d'un peu plus compliqué (gérer plusieurs clés):

#!/usr/bin/env perl
my %replace = ( 'dbName' => 'testdb', 'somethingElse' => 'fooBar' );
undef $/;
my $buf = <STDIN>;
$buf =~ s/\$\{$_\}/$replace{$_}/g for keys %replace;
print $buf;

Si vous nommez le script ci-dessus comme replace-script, il pourrait alors être utilisé comme suit:

replace-script < yourfile | mysql
Beau Simensen
la source
1
Fonctionne pour des variables uniques, mais comment puis-je inclure «ou» pour les autres?
Dana the Sane
2
Il y a de nombreuses façons de faire cela avec perl, tout en fonction de la complexité et / ou de la sécurité que vous vouliez faire. Des exemples plus compliqués peuvent être trouvés ici: perlmonks.org/?node_id=718936
Beau Simensen
3
Utiliser perl est tellement plus propre que d'essayer d'utiliser le shell. Prenez le temps de faire fonctionner cela plutôt que d'essayer certaines des autres solutions basées sur le shell mentionnées.
jdigital
1
Récemment dû s'attaquer à un problème similaire. En fin de compte, je suis allé avec perl (envsubst avait l'air prometteur pendant un moment, mais c'était trop difficile à contrôler).
sfitts le
5

Voici un moyen pour que le shell fasse la substitution à votre place, comme si le contenu du fichier était à la place tapé entre guillemets.

En utilisant l'exemple de template.txt avec le contenu:

The number is ${i}
The word is ${word}

La ligne suivante amènera le shell à interpoler le contenu de template.txt et à écrire le résultat dans la sortie standard.

i='1' word='dog' sh -c 'echo "'"$(cat template.txt)"'"'

Explication:

  • iet wordsont transmises en tant que variables d'environnement limitées à l'exécution de sh.
  • sh exécute le contenu de la chaîne qui lui est transmise.
  • Les chaînes écrites les unes à côté des autres deviennent une chaîne, cette chaîne est:
    • ' echo "' + " $(cat template.txt)" + ' "'
  • Puisque la substitution est entre ", " $(cat template.txt)" devient la sortie de cat template.txt.
  • Ainsi la commande exécutée par sh -cdevient:
    • echo "The number is ${i}\nThe word is ${word}",
    • iet wordsont les variables d'environnement spécifiées.
A priori
la source
Du point de vue de la sécurité, ce sont de mauvaises nouvelles. Si votre modèle contient, par exemple, '$(rm -rf ~)'$(rm -rf ~)les guillemets littéraux dans le fichier de modèle correspondent à ceux que vous avez ajoutés avant son expansion.
Charles Duffy
Je ne pense pas que les citations dans le modèle correspondent aux citations hors modèle, je pense que le shell résout le modèle et la chaîne dans le terminal indépendamment (suppression effective des guillemets) puis les concatène. Une version du test qui ne supprime pas votre répertoire personnel est '$(echo a)'$(echo a). Cela produit 'a'a. La principale chose qui se passe est que le premier echo aà l'intérieur de 'est évalué, ce qui n'est peut-être pas ce à quoi vous vous attendez puisqu'il est dans ', mais c'est le même comportement que l'inclusion 'dans une "chaîne entre guillemets.
Apriori
Donc, ce n'est pas sûr dans le sens où cela permet à l'auteur du modèle de faire exécuter son code. Cependant, la façon dont les citations sont évaluées n'affecte pas vraiment la sécurité. Développer tout ce qu'une "chaîne entre guillemets (y compris $(...)) est le point.
Apriori
Est-ce là le but? Je les vois seulement demander ${varname}, pas d'autres extensions à haut risque de sécurité.
Charles Duffy
... cela dit, je dois différer (re: les citations dans le modèle et hors modèle peuvent correspondre). Lorsque vous mettez un guillemet simple dans votre chaîne, vous vous divisez en une chaîne entre guillemets simples echo ", suivie d'une chaîne entre guillemets doubles avec les contetns littéraux de template.txt, suivie d'une autre chaîne littérale ", le tout concaténé en un seul argument passé à sh -c. Vous avez raison de dire que le 'ne peut pas être mis en correspondance (car il a été consommé par le shell externe plutôt que passé à l'intérieur), mais le "peut certainement, donc un modèle contenant Gotcha"; rm -rf ~; echo "pourrait être exécuté.
Charles Duffy
4

file.tpl:

The following bash function should only replace ${var1} syntax and ignore 
other shell special chars such as `backticks` or $var2 or "double quotes". 
If I have missed anything - let me know.

script.sh:

template(){
    # usage: template file.tpl
    while read -r line ; do
            line=${line//\"/\\\"}
            line=${line//\`/\\\`}
            line=${line//\$/\\\$}
            line=${line//\\\${/\${}
            eval "echo \"$line\""; 
    done < ${1}
}

var1="*replaced*"
var2="*not replaced*"

template file.tpl > result.txt
user976433
la source
2
Ce n'est pas sûr car il exécutera des substitutions de commandes dans le modèle s'ils ont une barre oblique inverse, par exemple\$(date)
Peter Dolberg
1
Mis à part le point valide de Peter: je vous suggère d'utiliser while IFS= read -r line; docomme readcommande, sinon vous supprimerez les espaces blancs de début et de fin de chaque ligne d'entrée. De plus, echopourrait confondre le début d'une ligne avec l'une de ses options de ligne de commande, il est donc préférable d'utiliser printf '%s\n'. Enfin, il est plus sûr de double-citer ${1}.
mklement0
4

Je suggérerais d'utiliser quelque chose comme Sigil : https://github.com/gliderlabs/sigil

Il est compilé en un seul binaire, il est donc extrêmement facile à installer sur les systèmes.

Ensuite, vous pouvez faire un simple one-liner comme suit:

cat my-file.conf.template | sigil -p $(env) > my-file.conf

C'est beaucoup plus sûr evalet plus facile que d'utiliser regex oused

spudfkc
la source
2
Très bonne réponse! C'est un système de modèles approprié et beaucoup plus facile à utiliser que les autres réponses.
Erfan
BTW, mieux vaut éviter catet utiliser à la <my-file.conf.templateplace afin de donner sigilun vrai handle de fichier au lieu d'un FIFO.
Charles Duffy
2

J'ai trouvé ce fil en me demandant la même chose. Cela m'a inspiré (attention aux backticks)

$ echo $MYTEST
pass!
$ cat FILE
hello $MYTEST world
$ eval echo `cat FILE`
hello pass! world
GlueC
la source
4
Un raccourci bash pour $(cat file)is$(< file)
glenn jackman
3
Apparemment, cette méthode gâche les sauts de ligne, c'est-à-dire que mon fichier a été renvoyé en une seule ligne.
Arthur Corenzan
@ArthurCorenzan: En effet, les sauts de ligne sont remplacés par des espaces. Pour résoudre ce problème, vous devez utiliser, eval echo "\"$(cat FILE)\""mais cela peut toujours être insuffisant dans la mesure où les guillemets doubles dans l'entrée sont ignorés.
mklement0
Comme cela a été noté ailleurs: utilisez cette option uniquement si vous faites entièrement confiance ou contrôlez l'entrée, car les substitutions de commandes ( `…` ou $(…)) intégrées dans l'entrée permettent l'exécution de commandes arbitraires en raison de l'utilisation de eval.
mklement0
2

Beaucoup de choix ici, mais je pensais que je mettrais le mien sur le tas. Il est basé sur Perl, ne cible que les variables de la forme $ {...}, prend le fichier à traiter comme argument et renvoie le fichier converti sur stdout:

use Env;
Env::import();

while(<>) { $_ =~ s/(\${\w+})/$1/eeg; $text .= $_; }

print "$text";

Bien sûr, je ne suis pas vraiment une personne perl, donc il pourrait facilement y avoir un défaut fatal (cela fonctionne pour moi cependant).

sfitts
la source
1
Fonctionne très bien. Vous pouvez supprimer la Env::import();ligne - l'importation est implicite par use. De plus, je suggère de ne pas commencer par créer la totalité de la sortie en mémoire: utilisez simplement print;au lieu de l' $text .= $_;intérieur de la boucle et supprimez la printcommande post-boucle .
mklement0
1

Cela peut être fait dans bash lui-même si vous avez le contrôle du format du fichier de configuration. Vous avez juste besoin de source (".") Le fichier de configuration plutôt que de le sous-shell. Cela garantit que les variables sont créées dans le contexte du shell actuel (et continuent d'exister) plutôt que du sous-shell (où la variable disparaît lorsque le sous-shell se termine).

$ cat config.data
    export parm_jdbc=jdbc:db2://box7.co.uk:5000/INSTA
    export parm_user=pax
    export parm_pwd=never_you_mind

$ cat go.bash
    . config.data
    echo "JDBC string is " $parm_jdbc
    echo "Username is    " $parm_user
    echo "Password is    " $parm_pwd

$ bash go.bash
    JDBC string is  jdbc:db2://box7.co.uk:5000/INSTA
    Username is     pax
    Password is     never_you_mind

Si votre fichier de configuration ne peut pas être un script shell, vous pouvez simplement le «compiler» avant de l'exécuter ainsi (la compilation dépend de votre format d'entrée).

$ cat config.data
    parm_jdbc=jdbc:db2://box7.co.uk:5000/INSTA # JDBC URL
    parm_user=pax                              # user name
    parm_pwd=never_you_mind                    # password

$ cat go.bash
    cat config.data
        | sed 's/#.*$//'
        | sed 's/[ \t]*$//'
        | sed 's/^[ \t]*//'
        | grep -v '^$'
        | sed 's/^/export '
        >config.data-compiled
    . config.data-compiled
    echo "JDBC string is " $parm_jdbc
    echo "Username is    " $parm_user
    echo "Password is    " $parm_pwd

$ bash go.bash
    JDBC string is  jdbc:db2://box7.co.uk:5000/INSTA
    Username is     pax
    Password is     never_you_mind

Dans votre cas spécifique, vous pouvez utiliser quelque chose comme:

$ cat config.data
    export p_p1=val1
    export p_p2=val2
$ cat go.bash
    . ./config.data
    echo "select * from dbtable where p1 = '$p_p1' and p2 like '$p_p2%' order by p1"
$ bash go.bash
    select * from dbtable where p1 = 'val1' and p2 like 'val2%' order by p1

Puis dirigez la sortie de go.bash dans MySQL et voilà, j'espère que vous ne détruirez pas votre base de données :-).

paxdiablo
la source
1
Vous n'avez pas à exporter les variables du fichier config.data; il suffit de les définir. Vous ne semblez pas non plus lire le fichier modèle à aucun moment. Ou peut-être que le fichier modèle est modifié et contient les opérations «écho» ... ou est-ce que je manque quelque chose?
Jonathan Leffler
1
Bon point sur les exports, je fais ça par défaut pour qu'ils soient disponibles pour les sous-shell et ça ne cause aucun mal puisqu'ils meurent quand ils sortent. Le fichier 'template' est le script lui-même avec ses instructions d'écho. Il n'est pas nécessaire d'introduire un troisième fichier - c'est essentiellement une opération de type mailmerge.
paxdiablo
1
Le "script lui-même avec ses instructions d'écho" n'est pas un modèle: c'est un script. Pensez à la différence de lisibilité (et de maintenabilité) entre <xml type = "$ TYPE"> et echo '<xml type = "' $ TYPE '">'
Pierre-Olivier Vares
1
@Pierre, il n'y a pas d'instructions d'écho dans mon script de configuration, ce sont simplement des exportations, et j'ai montré comment vous pouvez éviter même cela avec un minimum de pré-traitement. Si vous parlez de l'instruction echo dans mes autres scripts (comme go.bash), vous avez le mauvais bout du bâton - ils ne font pas partie de la solution, ils sont juste un moyen de montrer que les variables sont réglé correctement.
paxdiablo
1
@paxdiablo: Il semble que vous ayez oublié la question: << Je veux diriger la sortie d'un fichier "modèle" dans MySQL >>. Donc, l'utilisation d'un modèle EST la question, ce n'est pas "le mauvais bout du bâton". Exportation des variables et les écho dans un autre script ne répond pas seulement la question du tout
Pierre-Olivier Vares
0

Mise en place de l'édition perl de fichiers potentiellement multiples, avec des sauvegardes.

  perl -e 's/\$\{([^}]+)\}/defined $ENV{$1} ? $ENV{$1} : ""/eg' \
    -i.orig \
    -p config/test/*
Joehep
la source
0

Vous voudrez quelque chose de plus robuste que les suggestions actuelles car bien qu'elles fonctionnent pour votre cas d'utilisation limité (pour l'instant), elles ne suffiront pas pour des situations plus complexes.

Vous avez besoin d'un meilleur moteur de rendu. Vous avez besoin du meilleur moteur de rendu. Vous avez besoin de The Renderest!

Template.txt donné:

Salut toi}}!

Courir:

$ person = Bob ./render template.txt

Et vous verrez la sortie

Bonjour bob!

Écrivez-le dans un fichier en redirigeant stdout vers un fichier:

$ person = Bob ./render template.txt> rendu.txt

Et si vous effectuez le rendu d'un script contenant des variables $ {} que vous ne voulez pas interpoler, The Renderest vous couvre sans que vous ayez à faire autre chose!

Continuez et obtenez votre copie sur https://github.com/relaxdiego/renderest

Mark Maglana
la source