我正在运行MacOS Ventura 13.4,我想使用SED将以下meta标签(以给定的顺序)插入位于名为public的目录下的HTML文件index.html

<meta http-equiv='cache-control' content='no-cache'> 
<meta http-equiv='expires' content='0'> 
<meta http-equiv='pragma' content='no-cache'>

我有以下脚本:

#!/bin/bash

sed  -e '/\<head\>/a<meta http-equiv="pragma" content="no-cache">' \
     -e '/\<head\>/a<meta http-equiv="expires" content="0">' \
     -e '/\<head\>/a<meta http-equiv="cache-control" content="no-cache">' > public/index.html

但是,这引发了以下错误:

sed: 1: "/<head>/a<meta http-e ...": command a expects \ followed by text

任何想法如何解决这一问题?

分析解答

正如错误消息所说的那样,MacOS sed希望文本插入具有后斜线。

我还猜想您的意思是<head>,不仅是任何一侧具有单词边界的head(如果是您需要的话,MacOS上的语法(通常在POSIX上)是[[:<:]][[:>:]] (sic))。

sed -e '/<head>/a\
<meta http-equiv="cache-control" content="no-cache">\
<meta http-equiv="expires" content="0">\
<meta http-equiv="pragma" content="no-cache">'

您不能嵌套单引号,因此我切换到属性围绕属性的双引号。如果您真的需要单语引号,请尝试'"'"''"'"'结束了sed -e之后开始的字符串的单引号,开始双引号,唯一的文字单引号,结束双引号,启动单引号以继续长字符串)。

您没有透露标准输入应该来自何处;您的意思是与sed -i ''一起运行吗?虽然您不能在文件名之前使用重定向。

sed -i '' -e '/<head>/a\
<meta http-equiv="cache-control" content="no-cache">\
<meta http-equiv="expires" content="0">\
<meta http-equiv="pragma" content="no-cache">' public/index.html

(请注意,这将永久更改原始文件。如果不是您想要的,请不要使用-i。)

从技术上讲,<head之后的关闭楔形不需要与header名称相邻,甚至在同一行上。如果您需要完整的鲁棒性,则sed仅仅是错误的工具(或者,Turing已完成,因此如果您真的愿意,您可以实现适当的XML解析器;但实际上,您不这样做)。在MacOS上,也许会查看xmllint工具,该工具包含在开箱即用(至少使用Xcode)或xmlstarlet(例如xmlstarlet)的适当XML工具。