Comment insérer des variables dans une chaîne contenant ""?

25

Je veux construire une chaîne xml en insérant des variables:

str1="Hello"
str2="world"

xml='<?xml version="1.0" encoding="iso-8859-1"?><tag1>$str1</tag1><tag2>$str2</tag2>'

echo $xml

Le résultat devrait être

<?xml version="1.0" encoding="iso-8859-1"?><tag1>Hello</tag1><tag2>world</tag2>

Mais ce que je reçois c'est:

<?xml version="1.0" encoding="iso-8859-1"?><tag1>$str1</tag1><tag2>$str2</tag2>

J'ai aussi essayé

xml="<?xml version="1.0" encoding="iso-8859-1"?><tag1>$str1</tag1><tag2>$str2</tag2>"

Mais cela supprime les guillemets internes et donne:

<?xml version=1.0 encoding=iso-8859-1?><tag1>hello</tag1><tag2>world</tag2>
Super mario
la source
2
Un document XML ne peut pas avoir 2 balises de niveau supérieur. De plus, c'est 2016, je recommanderais fortement d' utiliser utf-8, pas iso-8859-1.
Celada

Réponses:

29

Vous ne pouvez incorporer des variables que dans des chaînes entre guillemets doubles.

Un moyen simple et sûr de faire ce travail est de sortir de la chaîne entre guillemets comme ceci:

xml='<?xml version="1.0" encoding="iso-8859-1"?><tag1>'"$str1"'</tag1><tag2>'"$str2"'</tag2>'

Notez qu'après avoir rompu la chaîne entre guillemets simples, j'ai enfermé les variables entre guillemets doubles. Il s'agit de sécuriser la présence de caractères spéciaux dans les variables.

Puisque vous avez demandé un autre moyen, voici une alternative inférieure en utilisant printf:

xml=$(printf '<?xml version="1.0" encoding="iso-8859-1"?><tag1>%s</tag1><tag2>%s</tag2>' "$str1" "$str2")

Ceci est inférieur car il utilise un sous-shell pour obtenir le même effet, ce qui est un processus supplémentaire inutile.

Comme @steeldriver l'a écrit dans un commentaire, dans les versions modernes de bash, vous pouvez écrire comme ceci pour éviter le sous-shell:

printf -v xml ' ... ' "$str1" "$str2"

Puisqu'il printfs'agit d'un shell intégré, cette alternative est probablement en partie avec ma première suggestion en haut.

janos
la source
8

L'expansion variable ne se produit pas dans les chaînes de guillemets simples.

Vous pouvez utiliser des guillemets doubles pour votre chaîne et échapper aux guillemets doubles à l'intérieur avec \. Comme ça :

xml="<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><tag1>$str1</tag1><tag2>$str2</tag2>"

La sortie du résultat:

<?xml version="1.0" encoding="iso-8859-1"?><tag1>hello</tag1><tag2>world</tag2>
Sidahmed
la source