Jenkins执行Shell时如何用sed替换文件内变量对应的字符串
Jenkins Shell中sed路径替换失效的解决方法
失效原因
- 你定义的
WORKSPACE是带大量/的绝对路径,直接拼接在以/为分隔符的sed替换规则中时,路径内部的/会被sed识别为替换语法的分隔符,导致正则表达式解析错误,替换无法执行。 - 脚本中文件名部分写的
$SUB_PRODUCT_tmp存在变量名歧义:shell会将SUB_PRODUCT_tmp整体识别为一个变量名,而非你预期的「SUB_PRODUCT变量值 +_tmp后缀」的拼接结果。 - 零散的单引号拼接变量的写法很容易出现引号不配对、特殊字符解析异常的问题。
正确写法
sed支持自定义替换分隔符,选择路径中不会出现的字符(比如|、#、@)作为分隔符,就不需要手动给每一个/加转义符,脚本简洁且不容易出错。修正后的完整脚本如下:
#!/bin/sh WORKSPACE="/opt/Project/jenkins/XX/XX/XX/XX/XXX-XXX" echo "$WORKSPACE" PRODUCT="MyProject" SUB_PRODUCT="MySubProject" sed -i "s|${WORKSPACE}|/home/Projects/XXX/${PRODUCT}/common/XXX-${SUB_PRODUCT}|g" "polyspaceFiles_${SUB_PRODUCT}_tmp.opts"
写法说明
- 用双引号包裹整个sed替换表达式,shell会自动完成内部变量的展开,不需要拆分成多段单引号拼接变量,降低语法错误概率。
- 所有变量引用统一用
${}包裹,明确变量名的边界,避免和后续的固定字符拼接时出现变量名识别错误。 - 所有变量、文件路径都用双引号包裹,兼容变量值包含空格、特殊字符的场景,避免Jenkins任务中因为路径含特殊字符随机报错。
- 如果有特殊需求必须使用
/作为sed分隔符,需要先对变量内的/做转义处理,示例:
这种写法冗余度高、可读性差,非必要不使用。# 先转义变量里的斜杠 WORKSPACE_ESCAPED=$(echo "$WORKSPACE" | sed 's#/#\\/#g') PRODUCT_ESCAPED=$(echo "$PRODUCT" | sed 's#/#\\/#g') SUB_PRODUCT_ESCAPED=$(echo "$SUB_PRODUCT" | sed 's#/#\\/#g') sed -i "s/${WORKSPACE_ESCAPED}/\/home\/Projects\/XXX\/${PRODUCT_ESCAPED}\/common\/XXX-${SUB_PRODUCT_ESCAPED}/g" "polyspaceFiles_${SUB_PRODUCT}_tmp.opts"
内容的提问来源于stack exchange,提问作者user3122648
相关产品推荐
相关产品推荐

