sed 输出首先只在括号之间匹配

sed output first match only between brackets

使用 sed,我想提取方括号之间的第一个匹配项。 我无法想出匹配的正则表达式,因为 sed 在其正则表达式中似乎很贪婪。例如,给定正则表达式 \[.*\] - sed 将匹配第一个左括号和最后一个右括号之间的所有内容,这不是我想要的(感谢您对此的帮助)。

但在我想出一个正则表达式之前,我假设右括号后必须有一个 space,才能得到一个 regex that will let me continue my work \[[^ ]*\].

我已经用 grep 试过了,例如

$ echo '++  *+   ++ + [SPAM] foo(): z.y.o ## [x.y.z]----- ' | grep -oE '\[[^ ]*\]'
[SPAM]
[x.y.z]

我想在 sed 中使用正则表达式(而不是在 grep 中)并输出第一个匹配项(即 [SPAM])。我试过如下,但没能做到

$ echo '++  *+   ++ + [SPAM] foo(): z.y.o ## [x.y.z]----- ' | sed 's/\[[^ ]*\]//'
sed: 1: "s/\[[^ ]*\]//":  not defined in the RE

$ echo '++  *+   ++ + [SPAM] foo(): z.y.o ## [x.y.z]----- ' | sed 's/\(\[[^ ]*\]\)//'
++  *+   ++ + [SPAM] foo(): z.y.o ## [x.y.z]-----

如果你能帮助我,我将不胜感激:

  1. 构建正则表达式以匹配每个左方括号和右方括号之间的所有文本(参见上面的 grep 示例)
  2. 在 sed 中使用正则表达式并仅输出第一次出现的匹配项

你可以使用

grep -o '\[[^][]*]' <<< "$text"
sed -n 's/^[^[]*\(\[[^][]*]\).*//p' <<< "$text"

参见online demo详情:

  • grep -o '\[[^][]*]' - o仅输出满足模式的匹配子字符串:[,然后 [] 以外的零个或多个字符,然后是 ] char
  • sed -n 's/^[^[]*\(\[[^][]*]\).*//p':
    • -n - 抑制默认行输出
    • ^[^[]*\(\[[^][]*]\).* - 匹配字符串的开头,然后是 [ 以外的零个或多个字符,然后捕获到组 1 a [,然后是 [= 以外的任何零个或多个字符=13=] 和 ] 然后是一个 ] 字符,然后匹配字符串的其余部分
    • </code> - 用第 1 组值 </li> 替换匹配项 <li><code>p - 打印替换结果。

你可以使用这个 sed:

s='++  *+   ++ + [SPAM] foo(): z.y.o ## [x.y.z]----- '
sed -E 's/[^[]*(\[[^]]*\]).*//' <<< "$s"

[SPAM]

这里:

  • [^[]* 匹配 0 个或多个非 [ 字符
  • (\[[^]]*\]) 匹配 [...] 子串并在组 #1
  • 中捕获
  • .* 匹配字符串的其余部分直到结束
  • </code> 替换将第 1 组中捕获的值放回输出</li> </ul> <p><code>awk 解决方案也不错:

    awk 'match([=11=], /\[[^]]*\]/){print substr([=11=], RSTART, RLENGTH)}' <<< "$s"
    
    [SPAM]