it-swarm.asia

Değişkene karmaşık çok satırlı dize yazmanın temiz yolu

Bir bash betiği içindeki bir değişkene bazı karmaşık xml yazmak gerekiyor. Xml parçasının yaşayacağı yer olduğu için xml, bash betiğinin içinde okunabilir olmalıdır, başka bir dosya veya kaynaktan okunmaz.

Benim sorum şu ki, benim bash betiğimin içinde insan tarafından okunabilir olmasını istediğim uzun bir dizem varsa, bunun için en iyi yol nedir?

İdeal olarak şunu istiyorum:

  • karakterlerden kaçmak zorunda kalmamak
  • birden fazla çizgiyi kırmasını sağlayın
  • girintisini koru

Bu EOF veya başka bir şeyle yapılabilir mi, biri bana örnek verebilir mi?

örneğin.

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
112
ChrisInCambo

Bu, tırnaklardan kaçmaya gerek kalmadan metninizi değişkeninize koyacaktır. Ayrıca, dengesiz teklifleri (kesme işaretleri, yani '). Sentinel (EOF) etrafına tırnak işareti koymak, metnin parametre genişletmesini engeller. -d'' birden çok satır okumasına neden oluyor (satırsonlarını yoksay). read dahili bir Bash olduğundan, cat gibi harici bir komut çağırmayı gerektirmez.

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

Neredeyse oradaydın. Dizenizin Meclisi için cat kullanırsınız veya dizenin tamamını alıntılarsınız (bu durumda dizenizin içindeki tırnak işaretlerinden kaçmanız gerekir):

#!/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}"
27
joschi
#!/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}"

Bourne Shell ortamında iyi çalışmalı

14
schweiz

Aynı şeyi yapmanın başka bir yolu ...

Değişkenleri ve özel <<- komut satırının girilmesine izin vermek için her satırın başında sekme bırakan:

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

yarı: eof'dan önce boşluk yok ama sadece çizelge .

<?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>
  • mapfile bir dizideki tüm belgeyi okur.
  • sözdizimi "${Pattern[*]}" bu diziyi bir dizeye yayınlar.
  • Kullanırım IFS=";" Çünkü yok ; gerekli dizelerde
  • Sözdizimi while IFS=";" read file ...IFS komut dosyasının geri kalanı için değiştirilmesini önler. Burada, sadece read değiştirilmiş IFS kullanır.
  • çatal yok.
6
F. Hauri

Diğer cevapların çoğunda çok fazla köşe vakası var.

Boşluklar, sekmeler, IFS vb. İle ilgili herhangi bir sorun olmadığından emin olmak için, daha iyi bir yaklaşım "heredoc" yapısını kullanmaktır, ancak burada açıklandığı gibi uuencode kullanarak heredoc içeriğini kodlamaktır:

https://stackoverflow.com/questions/6896025/#11379627 .

2
Chris Johnson