Sed:捕获第一个 ( 和 ) 之间的文本

Sed: capture the text between the first ( and )

我有以下格式错误的文本:

<h1 id="page-title">ABCD TEXT TEXT ( QQQ-10-123-01)</h1>
<h1 id="page-title">ABCD TEXT TEXT (QQQ-10-123-02)</h1>
<h1 id="page-title">ABCD TEXT TEXT (QQQ-10-123-03 (QWERTY))</h1>

需要从中获取:

QQQ-10-123-01
QQQ-10-123-02
QQQ-10-123-03 (QWERTY)

即仅获取第一个“(”和“)”之间的文本,此时执行以下操作:

sed -n "s/.*<h1 id=\"page-title\">.*(\(.*\))<\/h1>.*//p" ./file.txt

并得到:

 QQQ-10-123-01
QQQ-10-123-02
QWERTY)

如您所见,只有第二行得到了正确处理,因为这一行是最准确的。忽略可能的空格和处理重复输入“(”和“)”会出现问题。有人可以给出解决问题的正确方向吗?

P.S。我需要解析超过 2k 行; sedawk 之间的性能会有很大差异吗?据我一直阅读和理解,sed 应该在速度上有一点好处。真的是这样吗?

使用sed

$ sed 's/[^(]*([[:space:]]\?\([^)]*)\?\)).*//' input_file
QQQ-10-123-01
QQQ-10-123-02
QQQ-10-123-03 (QWERTY)
$ sed -E 's/[^(]*\([[:space:]]?([^)]*\)?)\).*//' input_file
QQQ-10-123-01
QQQ-10-123-02
QQQ-10-123-03 (QWERTY)

使用任何 sed:

$ sed 's/[^(]*( *\(.*\)).*//g' file
QQQ-10-123-01
QQQ-10-123-02
QQQ-10-123-03 (QWERTY)