MacOS 上的 sed“未定义标签”

问题描述 投票:0回答:3

我最近发现这个简单的

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
明确指出MacOS版本的
sed
支持标签,那么为什么会出现这个错误,最重要的是如何解决它?

macos sed
3个回答
35
投票

一个快速解决方法是在字符串表达式前面添加一个空字符串:

''

例如: 而不是

sed -i 's/foo/bar/g' text.txt

写:

sed -i='' 's/foo/bar/g' text.txt

这应该适用于不同的操作系统(Linux、MacOS、Windows)


11
投票

标签的名称以第一个换行符结尾,而不是以分号结尾。有两种简单的方法可以解决这个问题。添加文字换行符:

 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: /'

6
投票

SO 上有很多类似的问题,但大多数都是由于平台之间

-i
的行为不同,所以这是不同的。

在这种情况下,问题相当简单:在BSD版本的

sed
中,标签引用似乎只能向后,而GNU版本允许使用前向引用。也就是说,在 MacOS 上,
:label
必须出现在 b label 之前。

解决方案是重写表达式以在分支之前定义标签,或者在上面的表达式的情况下实现分支是一种“如果此模式不存在......向前跳转”。在这种情况下,表达式可以扩展为首先不需要标签:

sed '/SUCCESSFUL/d ; /\s+\[java\]\s*/d; /\[java\]/s/\s\+\[java\]//; /Compiling/!d; /^\s*$$/d; s/^/monitor: /'

© www.soinside.com 2019 - 2024. All rights reserved.