【问题标题】:sed command not working properly in solaris but working in linuxsed 命令在 solaris 中无法正常工作,但在 linux 中工作
【发布时间】:2014-03-14 12:22:06
【问题描述】:

我有以下在 sed 命令中进一步使用的字符串。它在 Linux 中正常工作,但在 Solaris 中不工作

-bash-3.00$ string="CREATESETTABLEDATABASE1.TABLE1(uid)CREATESETTABLEDATABASE1.TABLENAMEuid,cid,mid)DATABASE2.TABLENAME(hi,hello)"

在Linux框中,正确输出如下。

echo $string | sed -e 's/.*CREATESETTABLE[^)]\+TABLENAME\(.*\)/\1/g'
uid,cid,mid)DATABASE2.TABLENAME(hi,hello)

我是 solaris,sed 搜索不工作返回完整的字符串,不管搜索字符串匹配。

echo $string | sed -e 's/.*CREATESETTABLE[^)]\+TABLENAME\(.*\)/\1/g'
CREATESETTABLEDATABASE1.TABLE1(uid)CREATESETTABLEDATABASE1.TABLENAMEuid,cid,mid)DATABASE2.TABLENAME(hi,hello)

我希望在 solaris 中打印相同的输出。

【问题讨论】:

  • 哪个 Solaris 版本? Solaris 11 包含 GNU sed 命令(您在 Linux 上使用的命令)/usr/gnu/bin/sed - 您也可以下载 GNU sed 并在旧版本上自行安装。

标签: regex linux bash sed solaris


【解决方案1】:

我相信\+ 不能在旧的 sed 上工作,即使在 BSD 上也不支持。试试这个 sed:

sed -e 's/.*CREATESETTABLE[^)]*TABLENAME\(.*\)/\1/g'

【讨论】:

  • sed -e 's/.*CREATESETTABLE[^)]\{1,\}TABLENAME(.*)/\1/g'
  • + 和 * 之间有什么功能区别吗?
  • @logan + 表示匹配一个或多个,* 表示匹配零个或多个。
  • @anubhava:所以如果我使用*,即使没有匹配的TABLENAME,也会导致上述示例的输出?
  • [^)]* 将表示除 ) 之外的任何字符的 0 个或多个匹配项。您当然可以使用 [^)]\{1,\} 进行 1 场或更多场比赛。
【解决方案2】:

POSIX sed 仅支持BRE(基本正则表达式),其中+ 没有特殊含义

关于 BRE 的一个重要的奇怪之处(相对而言)是 (){} 需要 \-escaping 以获得它们的特殊含义。那些字符,并且只有那些字符,需要这样的转义。在当代 (ERE) 表达式中需要相反的情况,\-转义它们需要禁用它们的特殊含义。

BRE 中转义的 (\) 非特殊字符的行为在规范中未定义

您的问题源于\+(连同\?,以及\(\) 中的\|)是GNU extensions

这些 BRE 扩展保留了 \ 前缀的约定,但是当 GNU sed 被赋予选项 -r 时,它将启用 ERE(扩展正则表达式),其中 + 具有现代含义(相当于{1,}) 并删除了对额外 \ 的要求。同理,标准BRE对?(或\?,相当于{0,1})没有特殊意义,-r也启用了这个功能。

如果您使用 GNU sed --posix 选项,这将禁用各种 GNU 扩展,并且您的脚本通常应该更便携(尽管可能更复杂)。差不多,在 GNU sed 4.2(2009 年 4 月)之前,--posix 选项没有禁用所有 BRE 扩展,您应该确保使用最新版本,以便非 POSIX 功能不会不要潜入。

使用{1,} 实现您想要的最便携的方式:

echo $string | sed --posix -e 's/.*CREATESETTABLE[^)]\{1,\}TABLENAME\(.*\)/\1/g'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多