2017-03-31 23 views
-2

如何:之前提取所有的字符串,我只得到了第一个如下提取字在bash所有匹配的字符前

$ echo "cc_dd:qqq www;aa_bb:ll fi;ee_ff:bb dd ee" | sed 's/:.*//g' 
$ cc_dd 
# want to print cc_dd aa_bb and ee_ff 
+0

这是为什么呢下来投票?理由会帮助我的下一篇文章,谢谢。 – rodee

+0

我没有downvote。但我认为目前的形式,这个问题有点误导。最后一个字符串:不只是“ee_ff”。这是整个串到最后:。你需要指定你需要提取多少个字符,或者你需要指定另一个字符(;)作为模式的开始 – jrook

回答

2

的grep方法:

s="cc_dd:qqq www;aa_bb:ll fi;ee_ff:bb dd ee" 
grep -Po '[^;:]+(?=:)' <<< $s 

-P选项,允许Perl正则表达式

-o选项,讲述只打印匹配的子

(?=:) - 正预测先行断言,保证所需的子后面:

输出:

cc_dd 
aa_bb 
ee_ff 

性能比较:

time (for i in {1..1000}; do grep -Po '[^;:]+(?=:)' <<< $s > /dev/null; done;) 

real 0m1.936s 
user 0m0.036s 
sys  0m0.236s 

time (for i in {1..1000}; do awk -v RS=\; '{split($0,a,":"); print a[1]}' <<< $s > /dev/null; done;) 

real 0m2.633s 
user 0m0.056s 
sys  0m0.264s 
+0

如果我有更多的3,该怎么办?打印为1美元,3美元和5美元将无法一直工作,其变量 – rodee

+0

@Krish,你应该在你的问题 – RomanPerekhrest

+0

提到你,对不起。 – rodee

2

awk来救援!

echo "cc_dd:qqq www;aa_bb:ll fi;ee_ff:bb dd ee" | 
awk -v RS=\; '{split($0,a,":"); print a[1]}' 

cc_dd 
aa_bb 
ee_ff 
0
awk -F'[;:]' '{print $1,$3,$5}' OFS='\n' file 

cc_dd 
aa_bb 
ee_ff