J'ai besoin d'écrire du xml complexe dans une variable à l'intérieur d'un script bash. Le xml doit être lisible à l'intérieur du script bash car c'est là que le fragment xml va vivre, il n'est pas lu à partir d'un autre fichier ou source.
Donc, ma question est la suivante: si j'ai une longue chaîne que je veux être lisible par l'homme dans mon script bash, quelle est la meilleure façon de procéder?
Idéalement, je veux:
Cela peut-il être fait avec EOF ou quelque chose, quelqu'un pourrait-il me donner un exemple?
par exemple.
String = <<EOF
<?xml version="1.0" encoding='UTF-8'?>
<painting>
<img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
<caption>This is Raphael's "Foligno" Madonna, painted in
<date>1511</date>-<date>1512</date>.</caption>
</painting>
EOF
Cela mettra votre texte dans votre variable sans avoir besoin d'échapper aux guillemets. Il traitera également les citations non équilibrées (apostrophes, c'est-à-dire '
). Mettre des guillemets autour de la sentinelle (EOF) empêche le texte de subir une expansion des paramètres. Le -d''
le fait lire plusieurs lignes (ignorer les nouvelles lignes). read
est un Bash intégré, il ne nécessite donc pas d'appeler une commande externe telle que cat
.
IFS='' read -r -d '' String <<"EOF"
<?xml version="1.0" encoding='UTF-8'?>
<painting>
<img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
<caption>This is Raphael's "Foligno" Madonna, painted in
<date>1511</date>-<date>1512</date>.</caption>
</painting>
EOF
Vous y êtes presque arrivé. Soit vous utilisez cat pour l'assemblage de votre chaîne, soit vous citez la chaîne entière (auquel cas vous devrez échapper les guillemets à l'intérieur de votre chaîne):
#!/bin/sh
VAR1=$(cat <<EOF
<?xml version="1.0" encoding='UTF-8'?>
<painting>
<img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
<caption>This is Raphael's "Foligno" Madonna, painted in
<date>1511</date>-<date>1512</date>.</caption>
</painting>
EOF
)
VAR2="<?xml version=\"1.0\" encoding='UTF-8'?>
<painting>
<img src=\"madonna.jpg\" alt='Foligno Madonna, by Raphael'/>
<caption>This is Raphael's \"Foligno\" Madonna, painted in
<date>1511</date>-<date>1512</date>.</caption>
</painting>"
echo "${VAR1}"
echo "${VAR2}"
#!/bin/sh
VAR1=`cat <<EOF
<?xml version="1.0" encoding='UTF-8'?>
<painting>
<img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
<caption>This is Raphael's "Foligno" Madonna, painted in
<date>1511</date>-<date>1512</date>.</caption>
</painting>
EOF
`
echo "VAR1: ${VAR1}"
Cela devrait fonctionner correctement dans l'environnement Bourne Shell
J'aime utiliser des variables et des <<-
Spéciaux qui suppriment la tabulation au début de chaque ligne pour permettre l'indentation du script:
#!/bin/bash
mapfile Pattern <<-eof
<?xml version="1.0" encoding='UTF-8'?>
<painting>
<img src="%s" alt='%s'/>
<caption>%s, painted in
<date>%s</date>-<date>%s</date>.</caption>
</painting>
eof
while IFS=";" read file alt caption start end ;do
printf "${Pattern[*]}" "$file" "$alt" "$caption" "$start" "$end"
done <<-eof
madonna.jpg;Foligno Madonna, by Raphael;This is Raphael's "Foligno" Madonna;1511;1512
eof
avertissement: il n'y a pas d'espace vide avant eof
mais seulement tabulation .
<?xml version="1.0" encoding='UTF-8'?>
<painting>
<img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
<caption>This is Raphael's "Foligno" Madonna, painted in
<date>1511</date>-<date>1512</date>.</caption>
</painting>
"${Pattern[*]}"
transforme ce tableau en chaîne.IFS=";"
Car il n'y a pas de ;
Dans les chaînes obligatoireswhile IFS=";" read file ...
Empêche la modification de IFS
pour le reste du script. En cela, seul read
utilise le IFS
modifié.Il y a trop de cas de coin dans la plupart des autres réponses.
Pour être absolument sûr qu'il n'y a aucun problème avec les espaces, les tabulations, les IFS, etc., une meilleure approche consiste à utiliser la construction "heredoc", mais à coder le contenu de l'hérédoc en utilisant uuencode
comme expliqué ici: