sed 命令不适用于正则表达式

The sed command is not working with regex

我正在使用 sed 解析 HTTP GET 请求的输出,以检索给定 html 标记的内容。该请求的结果是这样的:

"<!DOCTYPE html><html><body><h1>Hello!</h1><p>v1.0.4-b</p></body></html>"

我想检索 p 元素中的版本号。

但是,sed 似乎在 regex 解析中存在错误。 当我使用:

sed 's/.*<p>//'

它正确地替换了版本左侧的文本(即,它输出 "v1.0.4-b</p></body></html>")。但是,当我尝试使用正则表达式组时,

sed 's/.*<p>(.*)<\/p>.*//'

匹配失败报错:

sed: -e expression #1, char 20: invalid reference on `s' command's RHS.

尽管如此,当我在在线正则表达式验证器上测试 regex 时它仍然有效。

提前致谢

你需要使用

sed -n 's~.*<p>\([^<]*\)</p>.*~~p'
sed -n -E 's~.*<p>([^<]*)</p>.*~~p'

online demo:

#!/bin/bash
sed -n 's~.*<p>\([^<]*\)</p>.*~~p' <<< \
 "<!DOCTYPE html><html><body><h1>Hello!</h1><p>v1.0.4-b</p></body></html>"
## => v1.0.4-b

sed 's/.*<p>(.*)<\p>.*//' 命令无法工作,因为

  • 您正在使用 POSIX BRE 模式,其中未转义的 () 被视为文字括号字符,而不是捕获组。在 POSIX BRE 中,你需要 \(...\) 来定义一个捕获组(这就是你得到 invalid reference 异常的原因)
  • 如果你添加-E选项来启用POSIX ERE,你可以使用(...)定义一个捕获组
  • 您没有匹配 /p,您的模式中有 \p

由于模式中有斜杠,所以选择正则分隔符比/更方便,我这里选择~

此外,我使用 -n 选项来抑制默认行输出,并使用 p 标志仅打印替换结果。