干净的方式来写一个复杂的多行string到一个variables

我需要写一些复杂的XML到bash脚本中的variables。 xml需要在bash脚本中可读,因为这是xml片段的存放位置,而不是从另一个文件或源读取的。

所以我的问题是,如果我有一个很长的string,我想在我的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 

这将把你的文本放入你的variables,而不需要转义引号。 它也将处理不平衡的引号(撇号)。 在引号(EOF)周围加上引号可防止文本进行参数扩展。 -d''使它读取多行(忽略换行符)。 read是一个内置的Bash,所以它不需要调用一个外部的命令,如cat

 read -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 

你几乎在那里。 您可以使用cat来组装您的string,也可以引用整个string(在这种情况下,您必须将string中的引号转义):

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

这应该在Bourne shell环境中正常工作

还有另一种方法来做同样的事情

我喜欢使用variables和特殊的<<-谁在每行的开头放置制表符以允许脚本缩进:

 #!/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[*]}"将这个数组转换为一个string。
  • 我使用IFS=";" 因为没有; 在需要的string
  • while IFS=";" read file ...的语法 while IFS=";" read file ...阻止脚本的其余部分修改IFS 。 在这里,只有read使用修改后的IFS
  • 没有叉子。

在许多其他的答案中有太多的angular落案例。

要绝对确定空格,制表符,IFS等没有问题,更好的方法是使用“heredoc”构造,但使用uuencode对heredoc的内容进行编码,如下所述:

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