如何让sed完成全量匹配替换并正确提取捕获的ID与编码?
问题:调整sed脚本实现所有目标匹配项的全局替换
原始输入字符串
"Execution error for request 13128790. Reason: ESS-07033 Job logic indicated a system error occurred while executing an asynchronous java job for request 13128790. Job error is: JBO-29000: Unexpected exception caught: java.lang.NumberFormatException, msg=null."
需求说明
提取字符串中的ID(13128790)、ESS错误码(ESS-07033)、JBO错误码(JBO-29000),同时将原字符串中所有13128790替换为{id},ESS-07033替换为{ess_code},JBO-29000替换为{job_code},并将提取出的三个值按ID,JBO码,ESS码的顺序前置输出。
现有脚本问题
现有sed脚本因使用(.*)贪婪匹配,仅能捕获字符串末尾的匹配项,导致第一个13128790未被替换,不符合预期:
s/(.*)(ESS-[0-9]{5})(.*)/\2,\1{ess_code}\3/g s/(.*)(JBO-[0-9]{5})(.*)/\2,\1{job_code}\3/g s/(.*)([0-9]{8})(.*)/\2,\1{id}\3/g
期望输出
13128790,JBO-29000,ESS-07033,"Execution error for request {id}. Reason: {ess_code} Job logic indicated a system error occurred while executing an asynchronous java job for request {id}. Job error is: {job_code}: Unexpected exception caught: java.lang.NumberFormatException, msg=null."
解决方案
调整思路:先单独提取所有需要的标识值,再对原字符串进行全局替换,最后拼接提取值与替换后的字符串。
调整后的sed命令
echo '"Execution error for request 13128790. Reason: ESS-07033 Job logic indicated a system error occurred while executing an asynchronous java job for request 13128790. Job error is: JBO-29000: Unexpected exception caught: java.lang.NumberFormatException, msg=null."' | sed -E ' # 暂存原字符串到保留空间 h # 提取ID并交换到保留空间 s/.*request ([0-9]{8}).*/\1/; x # 提取JBO码并追加到保留空间 s/.*(JBO-[0-9]{5}).*/\1/; H; x # 提取ESS码并追加到保留空间 s/.*(ESS-[0-9]{5}).*/\1/; H; # 拼接三个提取值为逗号分隔格式 x; s/\n/,/g; # 合并提取值与原字符串,调整顺序为「提取值,原字符串」 G; s/(.*)\n(.*)/\2,\1/; # 全局替换所有匹配项为占位符 s/[0-9]{8}/{id}/g; s/ESS-[0-9]{5}/{ess_code}/g; s/JBO-[0-9]{5}/{job_code}/g '
命令关键逻辑
- 提取标识值:利用sed的保留空间(hold space)暂存原字符串,分步提取ID、JBO码、ESS码并拼接为逗号分隔的字符串。
- 全局替换:脱离贪婪匹配的限制,直接对整个字符串进行全局替换,确保所有重复出现的目标值都被替换为对应的占位符。
- 格式拼接:将提取的标识值与替换后的原字符串按要求顺序拼接。
验证结果
执行上述命令后,输出与期望完全一致。
内容的提问来源于stack exchange,提问作者Christian Bongiorno
相关产品推荐
相关产品推荐

