sed:替换部分正则表达式并保留前缀/后缀

时间:2017-05-29 07:35:45

标签: linux shell sed

我尝试使用 sed 替换文件中的某些字符串,并遇到了问题。

我有以下字符串:

TEMPLATE_MODULE
TEMPLATE_SOME_ERR
TEMPLATE_MORE_ERR

我想将 TEMPLATE_MODULE 替换为一些字符串以及以 TEMPLATE 开头并以 ERR 结尾的所有字符串,其中包含不同的字符串,如如下:

TEMPLATE_MODULE   ---> NEW_MODULE_NAME
TEMPLATE_SOME_ERR ---> NEW_MODULE_NAME_SOME_ERR
TEMPLATE_MORE_ERR ---> NEW_MODULE_NAME_MORE_ERR

替换TEMPLATE_MODULE非常简单:

find . -type f -print -exec sed -i "s/TEMPLATE_MODULE/NEW_MODULE_NAME/g" {} +

虽然我不知道如何处理另一部分。如果我查找以 TEMPLATE _ * 开头的字符串,我还会捕获 TEMPLATE_MODULE

我还想保留 SOME_ERR MORE_ERR 后缀,以便此解决方案不起作用:

find . -type f -print -exec sed -i "s/TEMPLATE_.*_ERR$/NEW_MODULE_NAME/g" {} +

有什么想法吗? 谢谢!

2 个答案:

答案 0 :(得分:2)

考虑此示例输入

$ cat ip.txt 
foo
TEMPLATE_MODULE
TEMPLATE_SOME_ERR
TEMPLATE_MORE_ERR
TEMPLATE_SOME_ERR xyz

使用多个s命令并捕获组

$ sed -E 's/\bTEMPLATE_MODULE\b/NEW_MODULE_NAME/g; s/\bTEMPLATE\w*(_(SOME|MORE)_ERR)\b/NEW_MODULE_NAME\1/g' ip.txt 
foo
NEW_MODULE_NAME
NEW_MODULE_NAME_SOME_ERR
NEW_MODULE_NAME_MORE_ERR
NEW_MODULE_NAME_SOME_ERR xyz
  • \b用于字边界。 \bcat\b仅与cat匹配且与scatcater不匹配
  • s/\bTEMPLATE_MODULE\b/NEW_MODULE_NAME/g会将TEMPLATE_MODULE替换为NEW_MODULE_NAME
  • s/\bTEMPLATE\w*(_(SOME|MORE)_ERR)\b/NEW_MODULE_NAME\1/g将替换为TEMPLATE,后跟零个或多个以_SOME_ERR结尾的单词或_MORE_ERR NEW_MODULE_NAME以及捕获的字符串
  • 解决方案适用于GNU sed,不确定与其他实现的可移植性

答案 1 :(得分:0)

假设“TEMPLATE_MODULE”和“TEMPLATE_”是文字,但“SOME_ERR”和“MORE_ERR”是占位符,以下内容似乎是可能的。

sed "s/TEMPLATE\(_MODULE\)*/NEW_MODULE_NAME/"

我建议将其作为一个简单的sed行使用,然后,如果可以的话,将它集成到你的命令行中。

我认为这段代码并没有比你自己的代码更多地假设事件和拼写 但是,您可能希望使用“锚定”以免意外替换“SOMEOTHERTEMPLATE_”等。

首先,您需要修改此版本:

sed "s/\bTEMPLATE\(_MODULE\)*/NEW_MODULE_NAME/"

我建议尝试使用:

TEMPLATE_MODULE  
TEMPLATE_SOME_ERR  
TEMPLATE_MORE_ERR  
OTHER_TEMPLATE_MODULE  
OTHER_TEMPLATE_SOME_ERR