我最近发现这个简单的sed
表达式在Linux或Cygwin下正常工作但在Mac上因“未定义标签”错误而失败:
$ sed '/SUCCESSFUL/d ; /\[java\]/!b label; s/\s\+\[java\]//; /^\s*$$/d; /Compiling/!d; :label /^\s*$$/d; s/^/monitor: /'
sed: 1: "/SUCCESSFUL/d ; /\[java ...": undefined label 'label; s/\s\+\[java\]//; /^\s*$$/d; /Compiling/!d; :label /^\s*$$/d; s/^/monitor: /'
MacOS上的 sed
是BSD变体,具有与GNU对应物不同的选项。但man sed
清楚地表明sed
的MacOS版本支持标签,那么为什么会出现此错误,最重要的是如何解决?
答案 0 :(得分:5)
标签的名称以第一个文字换行符结束,而不是以分号结尾。有两种简单的方法可以解决问题。添加文字换行符:
sed '/SUCCESSFUL/d
/\[java\]/!b label
s/\s\+\[java\]//
/^\s*$$/d; /Compiling/!d
:label
/^\s*$$/d
s/^/monitor: /'
或使用多个-e
选项:
sed -e '/SUCCESSFUL/d ; /\[java\]/!b label' \
-e 's/\s\+\[java\]//; /^\s*$$/d; /Compiling/!d' \
-e':label' -e'/^\s*$$/d; s/^/monitor: /'
答案 1 :(得分:3)
在SO上有很多类似的问题,但大多数是由于-i
在平台之间存在差异的行为,所以这是不同的。
在这种情况下,问题很简单:似乎标签引用只能在sed
的BSD版本中倒退,而GNU版本允许使用前向引用。这是在MacOS上,:label
必须在 b label
之前出现。
解决方案是重写表达式以在分支之前定义标签,或者在上面的表达式的情况下,实现分支是一种“如果此模式不存在......向前跳”。在这种情况下,表达式可以扩展为首先不需要标签:
sed '/SUCCESSFUL/d ; /\s+\[java\]\s*/d; /\[java\]/s/\s\+\[java\]//; /Compiling/!d; /^\s*$$/d; s/^/monitor: /'