sed命令在Ruby脚本中执行异常,版本号截取错误排查
问题原因及解决方案
这个问题的核心是Ruby反引号执行shell命令时的字符串解析规则导致sed正则被篡改,具体来说:
在Bash中直接执行sed命令时,双引号里的\.会被Bash正确识别为字面意义的点号;但在Ruby的反引号字符串中,双引号内部的转义字符会被Ruby优先解析——你写的\.会被Ruby转成普通的.,导致sed实际收到的正则表达式和你预期的不一样。
看你正则的最后部分:原本是\.?(匹配可选的字面点号),经过Ruby解析后变成了.?——这就变成了匹配任意单个字符(可选)。所以处理字符串时,正则不仅匹配了-1.0.152.,还额外匹配了后面的w(因为.?可以匹配任意字符),把-1.0.152.w整个替换成.,最后就得到了abc-de-sap-web.ar。
解决方法
方法1:改用单引号包裹sed正则
把sed命令的双引号换成单引号,这样Ruby不会解析单引号内部的转义字符,sed能拿到完全符合预期的正则:
tar_name = `echo "abc-de-sap-web-1.0.152.war" | sed -E 's/\-[0-9]+\.[0-9]+\.[0-9]+\-?[0-9]*\.?[0-9]*\-?[0-9]*\.?/./g'` puts tar_name.strip # 输出 abc-de-sap-web.war
方法2:转义Ruby双引号里的反斜杠
如果一定要用双引号,需要把正则里的\.写成\\.,让Ruby解析后传给sed的依然是\.:
tar_name = `echo "abc-de-sap-web-1.0.152.war" | sed -E "s/\-[0-9]+\\.[0-9]+\\.[0-9]+\-?[0-9]*\\.?[0-9]*\-?[0-9]*\\.?/./g"` puts tar_name.strip # 输出 abc-de-sap-web.war
方法3:用Ruby原生字符串处理更优雅
既然是在Ruby脚本里,完全可以不用调用外部的sed命令,直接用Ruby的正则替换完成任务,更高效也更易维护:
original_str = "abc-de-sap-web-1.0.152.war" tar_name = original_str.gsub(/\-(\d+\.){2}\d+(-?\d*\.*\d*)*\.?/, '.') puts tar_name # 输出 abc-de-sap-web.war
内容的提问来源于stack exchange,提问作者Nanda Kishore Reddy
相关产品推荐
相关产品推荐

