我有像"(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/).*//'