Jak wstawić zmienne do ciągu zawierającego „”?

25

Chcę zbudować ciąg xml wstawiając zmienne:

str1="Hello"
str2="world"

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

echo $xml

Wynik powinien być

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

Ale dostaję:

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

Też próbowałem

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

Ale to usuwa wewnętrzne podwójne cudzysłowy i daje:

<?xml version=1.0 encoding=iso-8859-1?><tag1>hello</tag1><tag2>world</tag2>
supermario
źródło
2
Dokument XML nie może zawierać 2 znaczników najwyższego poziomu. Poza tym jest rok 2016, zdecydowanie polecam używanie utf-8, a nie iso-8859-1.
Celada,

Odpowiedzi:

29

Zmienne można osadzać tylko w ciągach cudzysłowów.

Łatwym i bezpiecznym sposobem na wykonanie tej pracy jest wyrwanie się z ciągu pojedynczego cudzysłowu:

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

Zauważ, że po wyrwaniu się z łańcucha pojedynczego cudzysłowu zawarłem zmienne w cudzysłowach. Ma to na celu bezpieczne umieszczanie znaków specjalnych w zmiennych.

Ponieważ poprosiłeś o inny sposób, oto gorsza alternatywa przy użyciu printf:

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

Jest to gorsze, ponieważ wykorzystuje podpowłokę, aby osiągnąć ten sam efekt, co jest niepotrzebnym dodatkowym procesem.

Jak napisał @steeldriver w komentarzu, w nowoczesnych wersjach bash możesz pisać w ten sposób, aby uniknąć podpowłoki:

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

Ponieważ printfjest to wbudowana powłoka, ta alternatywa jest prawdopodobnie częściowo z moją pierwszą sugestią na górze.

Przestań krzywdzić Monikę
źródło
8

Zmienne rozwijanie nie występuje w ciągach pojedynczych cudzysłowów.

Możesz użyć podwójnych cudzysłowów dla swojego ciągu i uciec przed podwójnymi cudzysłowami za pomocą \. Lubię to :

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

Wynikowy wynik:

<?xml version="1.0" encoding="iso-8859-1"?><tag1>hello</tag1><tag2>world</tag2>
Sidahmed
źródło