Sed正则表达式,在Mac终端中提取字符串的一部分



我有像"(stuff/thing)"这样的样本数据,我正在尝试提取"thing"。

我在OSX的终端上做这件事,但我似乎不太能做到这一点。

这是最后一次失败的尝试

echo '(stuff/thing)' | sed -n 's/((.*))/1/p'

我会说:

$ echo '(stuff/thing)' | sed -n 's@.*/([^)]*))@1@p'
thing

我开始说:

$ echo '(stuff/thing)' | sed -n 's@.*/@@p'
thing)

注意,为了更好的可读性,我使用@作为sed分隔符。

然后,我想去掉来自)的内容。为此,我们必须使用([^)]*))捕获块,并使用1将其打印回。

所以所有这些都在做:

#                print the captured group
#                ^^
#                | 
   .*/([^)]*))@1
#  ^^^| ^^^^^ |
#   | | ------|---- all but )
#   | |       |
#   | ^^     ^^
#   | capture group
#   |
#  everything up to a /

为fedorqui的有用答案提供awk替代方案

awk使得基于分隔符将行解析为字段变得容易:

$ echo '(stuff/thing)' | awk -F'[()/]' '{print $3}'
thing
  • -F[()/]指定在将每个输入行分解为字段时,字符()/中的任何一个都应用作字段分隔符
  • $3指的是第三个字段(thing第三个字段,因为行以字段分隔符开始,这意味着字段1($1)是之前的空字符串

至于为什么sed命令不起作用

由于不是使用-E,因此必须使用基本正则表达式(BRE),其中,与直觉相反,括号必须是转义才能显得特别-反之亦然。

然而,主要的问题是,为了只输出行的部分,您必须匹配全部,并用感兴趣的部分替换它。

对于BRE,则为:

echo '(stuff/thing)' | sed -n 's/^.*/(.*))$/1/p'

对于ERE(扩展正则表达式),它将是:

echo '(stuff/thing)' | sed -En 's/^.*/(.*))$/1/p'`

还要注意的是,这两个命令在GNUsed中都能正常工作,因此问题不是Mac特有的(但请注意,激活ERE的-E选项是更知名的-r的别名)
也就是说,regex方言在不同的实现中确实有所不同GNUsed通常支持对POSIX授权的BRE和ERE的扩展

我将分两个简单的部分来完成这项工作-删除所有直到并包括斜杠的内容,然后删除从右括号开始的内容:

echo '(stuff/thing)' | sed -e 's/.*///' -e 's/).*//'

最新更新