2016-09-02 137 views
2

我在bash使用SED尝试替换匹配的所有字符串:文件全部替换字符串,使用通配符的替代

compile 'com.test.*:*' 

有:

compile 'com.test.*:+' 

其中*是一个通配符。

我的文件是这样的,这就是所谓的moo.txt:

compile 'com.test.common:4.0.1' 
compile 'com.test.streaming:5.0.10' 
compile 'com.test.ui:1.0.7' 

,我希望它看起来像这样:

compile 'com.test.common:+' 
compile 'com.test.streaming:+' 
compile 'com.test.ui:+' 

我试图用sed,如:

sed -i -- "s/compile \'com.test.*:.*\'/compile \'com.test.*:+\'/g" moo.txt 

但是这使得文件的样子:

compile 'com.test.*:+' 
compile 'com.test.*:+' 
compile 'com.test.*:+' 

任何想法如何在替代字段中正确使用通配符?

+2

查找捕获组。 – 123

回答

3

您匹配com.test之后的东西,但不能正确打印回来。

所以你确实匹配的东西,只是你不打印回来。相反,你要打印文字.*

sed "s/compile \'com.test.*:.*\'/compile \'com.test.*:+\'/g" 
#      ^^      ^^ 
#    match this     print back? NO 

要做到这一点,捕捉模式,并使用反向引用打印回。

sed -E "s/compile 'com.test(.*):.*'/compile 'com.test\1:+'/g" 
#       ^^^^      ^^ 
#     catch this    print back! now YES! 

看到我们正在重复“编译...”太多吗?这意味着我们可以捕获延伸到线的开始,因为反向引用都将它打印回:

sed -E "s/^(compile 'com.test.*):.*'/\1:+'/g" 
#   ^^^^^^^^^^^^^^^^^^^^^  ^^ 
#   capture all of this  print it back 

注意-E使用允许sed捕捉组只(...)。如果我们没有使用-E,我们应该做\(...\)

还请注意,您正在转义单引号,而没有必要,因为您在双引号内。

+0

真棒,谢谢,这工作。是否有可能添加许多反向引用,使您可以\ 1和\ 2等?当然是 – user2010496

+0

@ user2010496!您最多可以使用9个。检查例如“回声”你好“|” sed -r's/^([^] *)([^] *)([^] *)/ \ 3 _ \ 2 _ \ 1 /''。 – fedorqui

+0

这太漂亮了! – user2010496

1
$ sed -E "s/[^:]+$/+'/" moo.txt 
compile 'com.test.common:+' 
compile 'com.test.streaming:+' 
compile 'com.test.ui:+' 
  • [^:]+$比赛比:在行尾以外的所有字符
  • 如果十六进制转义允许,使用双引号

要只资格时使用sed -E 's/[^:]+$/+\x27/'避免外壳的解释可能性行有compile 'com.test在行首

sed -E "/^compile 'com.test/ s/[^:]+$/+'/" moo.txt