sed 在 MacOS 上的“未定义标签”

Posted

技术标签:

【中文标题】sed 在 MacOS 上的“未定义标签”【英文标题】:sed "undefined label" on MacOS 【发布时间】:2012-08-29 14:52:19 【问题描述】:

我最近发现这个简单的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版本支持标签,那么为什么会出现这个错误,最重要的是如何解决呢?

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

这适用于标签定义命令以及引用标签的分支命令。我在 POSIX 中没有看到任何内容表明这些命令不必遵守分号约定。为什么苹果不解决这些问题?它仍然存在于 M1 上的最新 Mac OS 中。【参考方案2】:

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

【讨论】:

+1 和很好的收获。它还有助于将问题可视化为缩进代码,而不是单线 :-) 祝你好运。【参考方案3】:

对于遇到类似问题的其他人(在 MacOS 上)的快速解决方法可能是:

在您的字符串表达式前添加一个空字符串:''

例如: 而不是

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

写:

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

【讨论】:

以上是关于sed 在 MacOS 上的“未定义标签”的主要内容,如果未能解决你的问题,请参考以下文章

DICOM 未定义标签长度,PIXEL

AWS CLI / jq - 使用标签转换 JSON,甚至显示未定义标签的信息

"exit"未定义标签 问题

链接到 MacOS 上预编译的 QuantLib 二进制文件时未定义的 Boost 符号

macOS 上的 libfuzzer 未找到架构 x86_64

macOS 上的 Firefox 中未使用指定的字体 [关闭]