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]-----
如果你能帮助我,我将不胜感激:
- 构建正则表达式以匹配每个左方括号和右方括号之间的所有文本(参见上面的 grep 示例)
- 在 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]
使用 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]-----
如果你能帮助我,我将不胜感激:
- 构建正则表达式以匹配每个左方括号和右方括号之间的所有文本(参见上面的 grep 示例)
- 在 sed 中使用正则表达式并仅输出第一次出现的匹配项
你可以使用
grep -o '\[[^][]*]' <<< "$text"
sed -n 's/^[^[]*\(\[[^][]*]\).*//p' <<< "$text"
参见online demo。 详情:
grep -o '\[[^][]*]'
-o
仅输出满足模式的匹配子字符串:[
,然后[
和]
以外的零个或多个字符,然后是]
charsed -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]