我只想从特定的字符串中获取子字符串。
例如,我有"sec(name=test)"
字符串。而且,我想使用shell提取name=test
字符串。
我尝试过以下命令来提取"name=test"
值。但是,我的结果为sec()
echo "sec(name=test)"| grep -P '(sec\((.*)\))'
你能帮忙解决一下吗?
答案 0 :(得分:1)
你很接近,但除非你想egrep
(可能有或没有),sed
有基本正则表达式,例如
$ echo "sec(name=test)"| sed 's/^[^(]*(\([^)]*\)).*$/\1/'
name=test
标准替换命令的详细信息为s/find/replace/
,其中find
部分有点收集反向引用的设置,以便在replace
部分使用命令。例如,
find
部分
^
- 在字符串开头[^(]*
- 匹配[..class..]
中的所有字符"^("
(不是开场白)(
- 消耗开场白\(...\)
收集字符以保存为反向引用,这些字符为"[^)]*
所有内容都不是结束语,)
- 消耗闭幕式,.*$
- 其余部分。 replace
部分
\1
插入保存为第一个反向引用的字符(\(...\)
之间的内容name=test
。而且,你已经完成了......
答案 1 :(得分:0)
使用Gnu-Sed,你也可以写
echo "sec(name=test)"| sed -r 's/sec\(([^)]*)\)/\1/'
使用sed -r,当用于分组时,你的圆形parens不需要被屏蔽,但是当字面意思时。有关详细信息,请参阅 man sed 。
这会查找秒数(然后是任意数量的字符,不是关闭的数据,而是关闭的数据。
答案 2 :(得分:0)
grep
将打印匹配的行,或者-o
匹配的字符串。捕捉括号本身并没有做任何改变这一点。
grep -P
有一种方法可以说"匹配括号内的东西,但只有当以下的外观也符合"所以你可以做到
echo "sec(name=test)"| grep -oP '(?<=sec\().*?(?=\))'
后瞻(?<=sec\()
表示匹配必须紧跟sec(
,前瞻(?=\))
同样要求匹配后跟)
。我将匹配表达式从贪婪的.*
更改为吝啬的.*?
,以避免它跨越一组括号。当然,这可能不是你想要的;你的问题没有揭示我们应该期望匹配的文本(特别是,它可以包含嵌套的括号吗?)
但这很复杂;更简单和便携的解决方案是使用sed
替换所需字符串之前和之后的内容,然后打印。
echo "sec(name=test)"| sed -n 's/.*sec\(([^()]*)\).*/\1/p'
请注意sed
使用的正则表达式方法比grep -P
支持的正则方言更简单,特别是,未加引号的括号()
按字面意思匹配,而反斜杠的方言则用于分组 - 与他们在Perl中的工作方式相反,例如egrep
。