שאלה דרך נקייה לכתוב מחרוזת מרובת-שורות מורכבת למשתנה


אני צריך לכתוב קצת XML מורכבים למשתנה בתוך סקריפט bash. ה- XML ​​צריך להיות קריא בתוך התסריט bash כמו זה שם את קטע XML יחיה, זה לא להיות לקרוא מקובץ או מקור אחר.

אז השאלה שלי היא אם יש לי מחרוזת ארוכה אשר אני רוצה להיות קריא אנושית בתוך התסריט bash שלי מה היא הדרך הטובה ביותר ללכת על זה?

באופן אידיאלי אני רוצה:

  • לא צריך לברוח מכל הדמויות
  • יש לה לשבור שורות מרובות מה שהופך אותו קריא האדם
  • לשמור על זה הזחה

האם זה יכול להיעשות עם EOF או משהו, מישהו יכול לתת לי דוגמה?

למשל

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

94
2017-10-08 10:54




אני מוכן להתערב שאתה פשוט הולך לזרוק את הנתונים האלה לתוך זרם. למה לאחסן אותו משתנה כאשר אתה יכול לעשות דברים יותר מורכבים להשתמש הזרמים? - Zenexer
ראה גם: מחרוזת מרובת-שורות עם שטח נוסף (הזחה משומשת) - Yibo Yang


תשובות:


זה יהיה לשים את הטקסט שלך לתוך המשתנה שלך ללא צורך לברוח את המרכאות. זה יהיה גם להתמודד עם ציטוטים לא מאוזנים (Apostrophes, כלומר '). הצבת ציטוטים מסביב לזקיף (EOF) מונעת מהטקסט לעבור הרחבת פרמטרים. ה -d'' גורם לו לקרוא שורות מרובות (להתעלם newlines). read הוא Bash מובנית אז זה לא דורש לקרוא פקודה חיצונית כגון 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

123
2017-10-08 12:37



+1 כדי להימנע cat. - James Sneeringer
cat היא פקודה חיצונית. לא משתמש זה חוסך לעשות את זה. בנוסף, יש את הפילוסופיה שאם אתה משתמש חתול עם פחות משני טיעונים "אור לעשות את זה לא נכון" (אשר נבדל "שימוש חסר תועלת של cat"). - Dennis Williamson
ולעולם אף פעם לא הודע השני EOF .... (טבלה מרובים על הראש פוני מעורב) - IljaBek
ניסיתי להשתמש בהצהרה לעיל בעוד set -e. נראה ש read תמיד חוזר לא אפס. אתה יכול עבה התנהגות זו באמצעות ! read -d ....... - krissi
ואם אתה משתמש זה רב קו String משתנה לכתוב לקובץ, לשים את המשתנה סביב "ציטוטים" כמו echo "${String}" > /tmp/multiline_file.txt או echo "${String}" | tee /tmp/multiline_file.txt. לקח לי יותר משעה למצוא את זה. - Aditya


כמעט הגעת. או שאתה משתמש חתול עבור הרכבה של המחרוזת שלך או שאתה מצטט את כל המחרוזת (ובמקרה זה אתה צריך לברוח את הציטוטים בתוך המחרוזת שלך):

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

25
2017-10-08 11:14



למרבה הצער, הגלות ב"רפאל "גורמת לכך שהראשון לא עובד. - Dennis Williamson
שתי המטלות לעבוד בשבילי בסופו של דבר. ציטוט יחיד VAR1 לא צריך להיות בעיה (לפחות לא עבור באש). אולי אתה שולל על ידי הדגשת תחביר? - joschi
זה עובד בכתב, אבל לא בשא הפקודה. ללא שם: מצטער לא להיות ברורה יותר. - Dennis Williamson
עדיף לצטט את EOF 'EOF' או "EOF", אחרת משתנים פגז יהיה לנתח. - Stanislav German-Evtushenko


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


9
2017-09-05 15:54



+1 פתרון זה מאפשר החלפה משתנה כמו $ {foo} - Offirmo
הפוך: תואם sh. Downside: backticks הם הוצא משימוש / discouraged ב bash. עכשיו אם הייתי צריך לבחור בין ש ... - Zenexer
שכן כאשר backticks הוצא משימוש / discouraged? רק סקרן - Alexander Mills


דרך נוספת לעשות את אותו הדבר ...

אני אוהב להשתמש במשתנים מיוחדים <<- מי טיפה טבלאות בתחילת כל שורות כדי לאפשר הזחה 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

אזהרה: אין חלל ריק לפני 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>
כמה הסברים:
  • Mapfile לקרוא כולו כאן המסמך במערך.
  • התחביר "${Pattern[*]}" לעשות את המערך הזה לתוך מחרוזת.
  • אני משתמש IFS=";" בגלל שאין ; במיתרים הנדרשים
  • התחביר while IFS=";" read file ... למנוע IFS כדי לשנות את שאר התסריט. רק בזה read לעשות שימוש לשנות IFS.
  • אין מזלג.

4
2017-07-22 13:45



שים לב ש mapfile דורש באש 4 ומעלה. והתחביר "${Pattern[*]}" מטיל את המערך לתוך מחרוזת כאשר במרכאות (כפי שמוצג בקוד לדוגמה). - Dennis Williamson
כן, באש 4 היה מאוד חדש כאשר שאלה זו נשאלה. - F. Hauri


יש יותר מדי מקרים בפינה ברבות מהתשובות האחרות.

כדי להיות בטוח לחלוטין אין בעיות עם רווחים, כרטיסיות, IFS וכו ', גישה טובה יותר היא להשתמש "heredoc" לבנות, אבל לקודד את התוכן של heredoc באמצעות uuencode כפי שמוסבר כאן:

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


2
2018-05-17 09:10