Sed未能使用字符类匹配非空格字符

4
我想要提取在/etc/lvm/lvm.conf中配置的过滤规则,例如filter = [ "r|/dev/sda|" ]。我希望sed返回"r|/dev/sda|"。因此,我尝试了以下脚本: echo ' filter = [ "r|/dev/sda|" ] ' | sed -r 's:^\s*filter\s*=\s*\[\s*([^\s]+)\s*\]:\1:g' 但它没有起作用,脚本返回了filter = [ "r|/dev/sda|" ]。我已经尝试了一些在线正则表达式测试工具,该组已被正确匹配。
然而,如果我用.+替换[^\s]+,它就可以工作了。
难道[^\s]+不是表示一个以上的非空白字符吗?
请问你有什么主意吗?

1
这些速记符号不能在否定的括号表达式内使用。[^[:space:]] 可以使用。 - Wiktor Stribiżew
是的!!谢谢你,非常感谢你,@WiktorStribiżew - vesontio
如果您熟悉 grep 命令,请尝试使用 grep -oP 'filter.*\K".*?"' inputfile 进行过滤。 - P....
@PS. \K代表什么意思? - vesontio
这是一种“Perl”语言的表达方式,意思是忽略\K之前的所有内容。@vesontio - P....
@vesontio,使用\S+而不是[]更容易。我已经在下面写出来了。 - grzesiekmq
3个回答

5
根据 regular-expressions.info 的说法:
一个关键的句法区别是,反斜杠在 POSIX 方括号表达式中不是元字符。因此,在 POSIX 中,正则表达式 [\d] 匹配 \d
所以,你需要用 [^[:space:]]除空格之外的任何字符)替换 [^\s]示例
echo ' filter = [ "r|/dev/sda|" ] ' | sed -E 's:^\s*filter\s*=\s*\[\s*([^[:space:]]+)\s*\]:\1:g'

输出:"r|/dev/sda|"

4

[^[:space:]] 相比,更加简单和短的方法是使用 \S+,而不需要使用方括号 []

\S 表示非空格字符。

echo ' filter = [ "r|/dev/sda|" ] ' | sed -r 's:^\s*filter\s*=\s*\[\s*(\S+)\s*\]:\1:g'

https://ideone.com/PxDX1Q


1
如果grep解决方案可行:
grep -oP 'filter.*\K".*?"' inputfile

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接