【问题标题】:sed returning different result on different platformssed 在不同平台上返回不同的结果
【发布时间】:2012-05-02 16:43:38
【问题描述】:

您好,在 x86 机器上使用以下命令(使用 /bin/sh)返回:<port>3<port>

test="port 3"
echo $test | sed -r 's/\s*port\s*([0-9]+)\s*/<port>\1<\/port>/'

但在基于 ARM 的网络交换机的 sh shell 上运行相同的命令会返回字符串 port 3。

如何在交换机上获得与在 x86 机器上相同的结果?在我看来,数字似乎没有被 [0-9] 捕获。

【问题讨论】:

    标签: linux sed embedded embedded-linux


    【解决方案1】:

    \s 是标准 sed 行为的 GNU sed 扩展。 GNU sed 是桌面/服务器 Linux 系统上的实现。大多数嵌入式 Linux 系统运行 BusyBox,这是一套实用程序,占用空间明显更小,功能更少。

    指定“任何空格字符”的标准方法是[:space:] character class。 BusyBox 支持它(至少,大多数 BusyBox 安装都支持;大多数 BusyBox 功能可以被剥离以减少占用空间)。

    BusyBox 也不支持-r 选项,您需要使用basic regular expression。在 BRE 中,\(…\) 标记组,并且没有 + 运算符,只有 *。

    echo "$test" | sed 's/[[:space:]]*port[[:space:]]*\([0-9][0-9]*\)[[:space:]]*/<port>\1<\/port>/'
    

    请注意,由于您没有在 $test 周围加上任何引号,因此 shell 对变量的值执行了分词和通配符扩展。也就是说,变量的值被视为以空格分隔的文件名列表,然后由单个空格连接。所以如果你省略引号,你不必担心不同类型的空格,你可以写echo $test | sed 's/ *port *([0-9][0-9]*) */&lt;port&gt;\1&lt;\/port&gt;/'。但是,如果 $test 是 port *,则结果将取决于当前目录中存在哪些文件。

    【讨论】:

    • 感谢 Gilles 的详细回复。
    【解决方案2】:

    并非所有 seds 都支持像 \s 这样的 reg-expression 简写。更便携的版本是

      test="port 3"
      echo "$test" | sed -r 's/[ ]*port[ ]*([0-9]+)[ ]*/<port>\1<\/port>/'
    

    如果您确实还需要检查制表符字符,只需将它们添加到 char 类(在所有 3 个位置),在我的示例中只包含空格字符,即 [ ] 位。

    输出

    <port>3</port>
    

    我希望这会有所帮助。

    【讨论】:

    • baltusaj :谢谢,我很高兴能帮上忙。我建议您接受@Giles 的回答,因为它可以更好地解释解决方案并且使用[:space:] 也更好,假设您的系统支持它(大多数都支持)。祝大家好运。
    • 您是第一个回答的人,但仍然根据您的建议接受了 Giles 的回答。
    • @baltusaj :很高兴为您服务。我知道当我写了一个没有被接受的更好的解释时,我不喜欢它,所以我很高兴与一个更好的答案分享代表点。祝你好运。
    猜你喜欢
    • 1970-01-01
    • 2012-06-12
    • 1970-01-01
    • 2018-07-19
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    相关资源
    最近更新 更多