Bash。循环中的字符串连接

Bash. String concatenation in loop

我想获取 sitemap.xml 文件并用新的时间戳替换 lastmod

sitemap.xml的例子:

<?xml version="1.0" encoding="UTF-8"?>
<urlset>
  <url>
    <lastmod>2020-08-02T07:30:53+00:00</lastmod>
    <priority>1.00</priority>
  </url>
  <url>
    <lastmod>2020-08-02T07:30:53+00:00</lastmod>
    <priority>0.80</priority>
  </url>
</urlset>

还有我的代码:

field=lastmod
timestamp="$(date --iso-8601=seconds)"
sitemap=""

IFS=$'\r\n'
for line in $(cat ./sitemap.xml)    
do
  case $line in
    *"<$field>"*"</$field>"* )
    pre=${line#*"<$field>"}
    suf=${line%"</$field>"*}
    line="${line%$pre}${timestamp}${line#$suf}"
    ;;
  esac
  sitemap=$sitemap$line$'\n'
done

# echo $sitemap > sitemap.xml
echo $sitemap

上面的代码应该读取文件,替换所需的标签并输出它们。在这里,我试图连接文件字符串以供以后保存。而且我正在尝试将 \n 添加到每一行。

但是这段代码的输出没有换行:

<?xml version="1.0" encoding="UTF-8"?>   <url>     <lastmod>2020-08-22T15:35:47+03:00</lastmod>     <priority>1.00</priority>   </url>   <url>     <lastmod>2020-08-22T15:35:47+03:00</lastmod>     <priority>0.80</priority>   </url> </urlset>

我做错了什么?

我没有看'what you are doing wrong',但这是一个替代方案(你只需要修改date的格式):

$ xmlstarlet ed -u //lastmod -v "`date`" sitemap.xml
<?xml version="1.0" encoding="UTF-8"?>
<urlset>
  <url>
    <lastmod>Sat Aug 22 14:51:59 CEST 2020</lastmod>
    <priority>1.00</priority>
  </url>
  <url>
    <lastmod>Sat Aug 22 14:51:59 CEST 2020</lastmod>
    <priority>0.80</priority>
  </url>
</urlset>

像这样:

$ xmlstarlet ed -u //lastmod -v "$(date --iso-8601=seconds)" sitemap.xml
<?xml version="1.0" encoding="UTF-8"?>
<urlset>
  <url>
    <lastmod>2020-08-22T14:53:46+02:00</lastmod>
    <priority>1.00</priority>
  </url>
  <url>
    <lastmod>2020-08-22T14:53:46+02:00</lastmod>
    <priority>0.80</priority>
  </url>
</urlset>

echo $sitemap替换为echo "$sitemap"

使用引号保留或追加换行符

Shell 引用和扩展规则可能很棘手。您需要将您的作业引用到 sitemap。例如:

sitemap="$sitemap$line"

您可能还需要将您的论点引用到 echo 中。如果你真的想在连接字符串的末尾附加一个换行符,你要么必须在引号外执行扩展,使用带回显的 -e 标志,要么只执行另一个回显。你也可以使用 printf。例如:

  • echo "${sitemap}${line}"$'\n'
  • echo -e "${sitemap}${line}\n"
  • printf "%s%s\n" "$sitemap" "$line"

如果您在其他地方需要换行符,您可以将它们四处移动,但原理仍然相同。