这真是一块牛黄。
DEMO_RE 是一个正则表达式。粗略地说,这意味着它是对另一个字符序列的描述。任何给定的字符序列要么匹配此正则表达式,要么不匹配。
DEMO_SED 是一个 sed 命令。在这个阶段,它只是一个 Make 变量,一个字符序列,但稍后可以将其传递给 shell(在 Make 变量扩展之后),shell 会将其解释为 sed 命令。
我并不完全理解这个 sed 命令,但这是我最好的尝试。从中间开始:
sed 's/${DEMO_RE}//'
Make 会将 ${DEMO_RE} 扩展为第一行中的 gobbledegook 字符串,查找与正在考虑的任何文本行匹配,并将匹配的文本更改为空(即删除它)。
sed 's/${DEMO_RE}//g'
s 命令的 g 修饰符意味着对所有匹配项进行替换(在本例中为删除),而不仅仅是找到的第一个匹配项。
sed -nE 's/${DEMO_RE}//g;p'
-n 表示默认不打印结果。 p 表示打印模式空间的内容,因此目前这些更改相互抵消。 E 表示将正则表达式解释为扩展正则表达式,而不是基本正则表达式。
sed -nE '{s/${DEMO_RE}//g;p}'
花括号将这些命令组合在一起。
sed -nE '${;g;s/${DEMO_RE}//g;p;}'
现在事情变得复杂了。 Sed 有第二个缓冲区,称为保持空间。 g 命令将保持空间的内容复制到模式空间(这是人们通常使用的缓冲区,也是大多数人知道的唯一一个)。在我们考虑将把东西放入 保持空间的其他命令之前,这并没有多大意义。 $ 意味着只有当 sed 到达输入的最后一行时,才应该应用这个命令(大括号的内容)。 我认为前导分号没有任何用途,但我不敢说它绝对没有任何作用。 现在我将省略替换命令以确保易读性。
sed -nE '$${;g;p;}'
由于 Make 尝试扩展以 $ 开头的内容,并且我们想将一个 '$' 原封不动地传递给 sed,因此我们用另一个 '$' 对其进行转义。 Make 会将$$ 扩展为$ 并将${... 传递给shell(它将传递给sed)。
sed -nE '1h;1!H;$${;g;p;}'
1h 表示将输入的第一行复制到保留空间。 1!H 表示将每一行 除了 第一行附加到保留空间。记住-n;在 sed 执行花括号中的命令组之前不会打印任何内容,这只会在读入最后一行输入时发生。所以:
sed -nE '1h;1!H;$${;g;s/${DEMO_RE}//g;p;}'
“将所有输入读入保留空间,不打印任何内容,然后在最后将其全部拉回,切除与(可能扩展的)匹配的所有内容,并打印剩下的所有内容。”
这个答案已经很长了;我可以给你一个正则表达式的粗略翻译,但是以一种不会混淆这个媒介的方式这样做是一种痛苦。它似乎想要匹配任何被script 标签或<!--[[ 或]]--> 包围的东西,所有这些都跟随到下一个标签。