【问题标题】:sed branching not working on OSX: undefined labelsed 分支在 OSX 上不起作用:未定义标签
【发布时间】:2022-01-02 17:26:14
【问题描述】:

我正在尝试修改来自 https://stackoverflow.com/a/66365284/1236401 的答案,该答案添加了控制流以提供匹配状态代码:

cat file.txt | sed 's/1/replaced-it/;tx;q1;:x'

它在 Ubuntu 和 Alpine 上按预期工作,但在 Mac OSX (11.6) 上失败,使用任何 shell。

sed: 1: "s/1/replaced-it/;tx;q1;:x": 未定义标签 'x;q1;:x'

我在 OSX 上找到的所有对sed 行为不端的引用都是针对就地文件编辑的,这里不是这种情况。

【问题讨论】:

  • 该问题已得到解答,但仅供参考,来自 POSIX 手册页:Command verbs other than {, a, b, c, i, r, t, w, :, and # can be followed by a <semicolon>, optional <blank> characters, and another command verb.。对于这些命令,您可以使用新行,或使用 -e(也是 POSIX)分成块。 “未定义标签”是 BSD sed 在标签中接受 ;,而在 GNU 中,命令分隔符的含义优先(这是与标准的偏差)。
  • sed 是一个很好的工具,可以在单独的行上进行简单的 s/old/new/ 替换,但是如果您有任何其他文本操作来执行代码,那么它将是更清晰、更健壮的组合,如果您使用 awk,则更便携、更高效。如果@triplee 的答案是否与 awk 等效,我知道 sed 咒语做了什么——如果不是,并且您添加简洁、可测试的样本输入和预期输出以及awk 标签,我们可以为您提供帮助。
  • 这可以写成sed '/1/{s//replaced-it/;q1}' filesed '/1/!b;s//replace-it/;q1' file

标签: macos sed


【解决方案1】:

AWK 等效项是:

awk '!sub(/1/,"replaced-it") {print; exit 1} 1' file.txt

如果替换不成功:打印并以状态 1 退出;否则打印。

【讨论】:

    【解决方案2】:

    这是一个 Awk 重构。

    awk '/1/ { sub("1", "replaced-it", $0); replaced=1 } 1
        END { exit 1-replaced }' file.txt
    

    还要注意the cat is useless(也有sed,通常是任何标准的Unix命令,除了烦人的tr)。

    【讨论】:

    • /1/ { sub("1", "replaced-it", $0); replaced=1 } = sub(/1/, "replaced-it"){ replaced=1 }
    • @EdMorton 谢谢,漂亮多了。
    【解决方案3】:

    sed 中的命令主要由换行符分隔。

    | sed 's/1/replaced-it/
      tx
      q1
      :x
    '
    

    或者:

    sed -e 's/1/replaced-it/' -e 'tx' -e 'q1' -e ':x'
    

    另外,q1 是一个 GNU sed 扩展 - 并非每个 sed 都支持它。它必须被删除、重构,或者你必须安装 GNU sed

    总的来说,用awk、python或perl写吧。

    【讨论】:

    • 仍然不适合我,都失败了extra characters at the end of q command
    • q1 是 gnu 扩展,普通 sed 不支持。
    猜你喜欢
    • 2012-08-29
    • 2012-11-13
    • 2018-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-23
    • 2013-09-11
    相关资源
    最近更新 更多