OracleLinux 8.9中sed执行出现Invalid RangeEnd错误求助
sed脚本在OracleLinux 8.9报错"invalid range end"的解决思路
问题概述
同一sed脚本在OracleLinux 7.9上可正常执行,但在OracleLinux 8.9运行时提示"invalid range end"错误,输出文件为空。
执行命令
sed -r -f ./sed/transform-diff.sed < 15-diffToUpdate.xml > 15-diffToUpdate.xml.tmp
错误信息
sed: file ./sed/transform-diff.sed line 11: Invalid range end
涉事sed脚本内容
# sed script to transform generated Liquibase diff file # Problem to solve: If a column is dropped, a RDBM drops as well every index, that uses these columns. In the # Liquibase diff script, columns are dropped first, indexes later. In the previously described case, an index # might already be deleted and the update might fail. # Solution: Put every <dropIndex> in a separate <changeSet>, containing a <indexExists> preCondition that # only executes the <dropIndex> if it still exists. /<changeSet/ { N s%([ \t]*)<changeSet author="([a-zA-Z \(\)]*)" id="([a-zA-Z0-9-]*)">[ \t\n]*(<dropIndex indexName="([a-zA-Z0-9_]*)"[a-zA-Z_-=" ]*>)%\1<changeSet author="\2" id="\3a">\n\1\1<preConditions onFail="CONTINUE">\n\1\1\1<indexExists indexName="\5" />\n\1\1</preConditions>\n\1\1\4\n\1</changeSet>\n\1<changeSet author="\2" id="\3b">%g } # Problem to solve: Liquibase diff reads from type FLOAT not the precision but the the required bytes adds # this information to its change log. A FLOAT (with default precision of 126) is transformed to a FLOAT(22), # which is too short. By removing all precision information in the generated diff file, we avoid this # problem. /type="FLOAT\(/ { s%type="FLOAT\([0-9]*\)"%type="FLOAT"%g }
测试环境验证
- Oracle Linux 7.9:脚本运行正常,成功生成输出文件
- Oracle Linux 8.9:触发错误,输出文件为空
错误原因与修复方案
错误根源
报错行(第11行)的正则表达式中,字符组[a-zA-Z_-=" ]*存在问题:在GNU sed的新版本(OracleLinux 8.9搭载的版本更高)中,字符组内的-若处于两个字符之间,会被解析为字符范围定义符。此处-_试图定义从_(ASCII码95)到=(ASCII码61)的字符范围,这是一个无效的反向范围(起始字符ASCII码大于结束字符),因此触发"Invalid range end"错误。而OracleLinux 7.9的sed版本对这类无效范围检测更宽松,未触发报错。
修复方法
修改第11行正则中的字符组,通过以下两种方式避免-被解析为范围符:
- 将
-移至字符组的开头或结尾:s%([ \t]*)<changeSet author="([a-zA-Z \(\)]*)" id="([a-zA-Z0-9-]*)">[ \t\n]*(<dropIndex indexName="([a-zA-Z0-9_]*)"[a-zA-Z_=" -]*>)%\1<changeSet author="\2" id="\3a">\n\1\1<preConditions onFail="CONTINUE">\n\1\1\1<indexExists indexName="\5" />\n\1\1</preConditions>\n\1\1\4\n\1</changeSet>\n\1<changeSet author="\2" id="\3b">%g - 用反斜杠
\转义-:s%([ \t]*)<changeSet author="([a-zA-Z \(\)]*)" id="([a-zA-Z0-9-]*)">[ \t\n]*(<dropIndex indexName="([a-zA-Z0-9_]*)"[a-zA-Z_\-=" ]*>)%\1<changeSet author="\2" id="\3a">\n\1\1<preConditions onFail="CONTINUE">\n\1\1\1<indexExists indexName="\5" />\n\1\1</preConditions>\n\1\1\4\n\1</changeSet>\n\1<changeSet author="\2" id="\3b">%g
修改后重新执行脚本,即可在OracleLinux 8.9上正常运行。
内容的提问来源于stack exchange,提问作者Uwe A
相关产品推荐
相关产品推荐

