替换文件中的所有字符串,在替换中使用通配符

问题描述 投票:2回答: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.*:+'

有关如何正确使用替换字段中的通配符的任何想法?

regex bash sed
2个回答
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,我们应该做\(...\)

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


1
投票
$ sed -E "s/[^:]+$/+'/" moo.txt 
compile 'com.test.common:+'
compile 'com.test.streaming:+'
compile 'com.test.ui:+'
  • [^:]+$匹配除了:之外的所有字符
  • 如果允许使用十六进制转义符,请在使用双引号时使用sed -E 's/[^:]+$/+\x27/'以避免shell解释的可能性

要符合条件,只有线路开头有compile 'com.test

sed -E "/^compile 'com.test/ s/[^:]+$/+'/" moo.txt
© www.soinside.com 2019 - 2024. All rights reserved.