您好,在 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] 捕获。
您好,在 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] 捕获。
\s
是标准 sed 行为的 GNU sed 扩展。GNU sed 是桌面/服务器 Linux 系统上的实现。大多数嵌入式 Linux 系统都运行BusyBox,这是一套实用程序,占用空间明显更小,功能更少。
指定“任何空格字符”的标准方法是[:space:]
字符类。BusyBox 支持它(至少,大多数 BusyBox 安装都支持;大多数 BusyBox 功能可以被剥离以减少占用空间)。
BusyBox 也不支持该-r
选项,您需要使用基本的正则表达式。在 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]*) */<port>\1<\/port>/'
. 但是,如果$test
是port *
,则结果将取决于当前目录中存在哪些文件。
并非所有 seds 都支持 reg-expression 简写,例如\s
. 更便携的版本是
test="port 3"
echo "$test" | sed -r 's/[ ]*port[ ]*([0-9]+)[ ]*/<port>\1<\/port>/'
如果您确实还需要检查制表符,只需将它们添加到 char 类(在所有 3 个位置),在我的示例中只包含空格字符,[ ]
即位。
输出
<port>3</port>
我希望这有帮助。