这一行直接来自FullCalendar(一个jQuery插件)Makefile。我无法理解它,尤其是带有美元符号的部分。我不知道make,shell还是sed“处理”它。我也不清楚其他(显然是?)sed命令。
DEMO_RE = (<script[^>]*_loader\.js[^>]*><\/script>|<!--\[\[|\]\]-->)[^<]*
DEMO_SED = sed -nE '1h;1!H;$${;g;s/${DEMO_RE}//g;p;}'
答案 0 :(得分:8)
那是一个牛黄。
DEMO_RE
是正则表达式。松散地说,这意味着它是对另一个字符序列的描述。任何给定的字符序列都与此正则表达式匹配或不匹配。
DEMO_SED
是一个sed命令。在这个阶段,它只是一个Make变量,一个字符序列,但稍后它可以传递给shell(在Make变量扩展之后),它将把它解释为sed命令。
我不完全理解这个sed命令,但这是我最好的尝试。从中间开始:
sed 's/${DEMO_RE}//'
Make会将${DEMO_RE}
扩展为第一行中gobbledegook的字符串,查找正在考虑的任何文本行的匹配项,并将匹配的文本更改为空(即删除它)。
sed 's/${DEMO_RE}//g'
g
命令的s
修饰符表示对所有匹配项进行替换(在本例中为删除),而不仅仅是找到的第一个匹配项。
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到达输入的最后一行时才应用此命令(花括号的内容)。 我没有看到领先分号的任何目的,但我不敢说它绝对没有。现在我省略了替换命令的易读性。< / p>
sed -nE '$${;g;p;}'
由于Make尝试扩展以$
开头的内容,我们希望传递一个&#39; $&#39;完整到sed,我们用另一个&#39; $&#39;逃脱它。 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;}'
&#34;将所有输入读入保留空间,不打印任何内容,然后将其全部拉回到最后,切除与(可能已扩展)相匹配的所有内容,并打印剩余的内容。&# 34;
这个答案变得很长;我可以给你一个关于正则表达式的粗略翻译,但是以一种不会混淆这种媒介的方式这样做是一种痛苦。它似乎想要匹配script
标记或<!--[[
或]]-->
所包围的任何内容,以及所有下一个标记的内容。
答案 1 :(得分:3)
Beta在分离sed脚本,逻辑块逻辑块方面做得非常出色。 sed脚本从输入文本中删除某些JavaScript块。他的最终总结可能就是你所需要的。如果你想要一个更短的答案,这里就是。
你提到的令人困惑的是美元符号。
┌ Double $ is actually just an "escaped" $ character
│ ┌ Starts a variable reference
│ │
'1h;1!H;$${;g;s/${DEMO_RE}//g;p;}'
│ │ │ │
│ └variable┘ │
└ Stuff run at EOF ───┘
第一对美元符号构成一个单一的美元符号,在文件的末尾将其解释为“#34;”。所以外部花括号之间的东西在EOF运行。内部大括号的形式为${VARNAME}
,这是Make引用变量的方式。它看起来像shell变量引用,但它不是。
在这种情况下,由于Make变量分配实际上并未执行任何操作,因此您的DEMO_SED
变量的内容为DEMO_RE
。具有讽刺意味的是,原因是这被分成两个变量,分开是为了使整个过程更具可读性。 : - )
请注意,这些执行任何内容(即sed)都不会。它只分配变量。稍后在你的Makefile中,你可能会有一个目标,其行可能类似于:
${DEMO_SED} path/to/file.html.orig > path/to/file.html
在那一点上,所有这些都变成了功能性的东西。