You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Bash中使用sed时如何保留转义的双引号?

问题

我先转义JSON字符串里的所有双引号,再用转义后的结果替换文本中的占位符,但最后一次sed替换中转义符被移除了,请问原因是什么?该如何避免?

Bash示例:

TEST_OBJECT='{"val1": "a", "val2": "b"}'

ESCAPED_OBJ="$(echo $TEST_OBJECT | sed 's/"/\\"/g')"

echo $ESCAPED_OBJ
# 输出:{\"val1\": \"a\", \"val2\": \"b\"}

echo 'value: "_REPLACE_ME"' | sed "s@_REPLACE_ME@$ESCAPED_OBJ@g"
# 实际输出:value: "{"val1": "a", "val2": "b"}"
# 期望输出:value: "{\"val1\": \"a\", \"val2\": \"b\"}"

补充说明
转义操作和替换操作必须分两步执行(这是GitHub工作流的一部分),最终要替换YAML文件中的占位符:

sed "s@_REPLACE_ME@$ESCAPED_OBJ@g" input.yml > ${{ github.action_path }}/config/job.yml

目标YAML文件job.yml内容:

...
env:
  - name: CUSTOM_DATA_OBJECT
    value: "_REPLACE_ME"

需要保留转义后的格式,避免破坏YAML结构。

原因

问题出在bash对双引号内变量的解析逻辑:
当你用双引号包裹sed命令(sed "s@...@$ESCAPED_OBJ@g")时,bash会先展开变量ESCAPED_OBJ,并解析其中的转义符——把\"直接转换成",传给sed的内容已经是没有转义符的原始JSON了,所以替换后自然看不到转义效果。

解决方案

要让sed最终保留\",需要让bash解析后传给sed的内容仍然是\",所以需要对转义符再转义一次:把\变成\\,这样bash解析时会把\\"转换成\",最终sed就能正确输出带转义的字符串。

具体实现步骤

  1. 重新生成转义后的字符串,同时转义转义符:
TEST_OBJECT='{"val1": "a", "val2": "b"}'
# 先转义双引号为\",再把\转义为\\,最终得到\\"
ESCAPED_OBJ="$(echo "$TEST_OBJECT" | sed 's/"/\\\\"/g')"

或者分两步处理:

# 第一步转义双引号
TEMP_OBJ="$(echo "$TEST_OBJECT" | sed 's/"/\\"/g')"
# 第二步转义转义符
ESCAPED_OBJ="$(echo "$TEMP_OBJ" | sed 's/\\/\\\\/g')"
  1. 执行替换命令:
echo 'value: "_REPLACE_ME"' | sed "s@_REPLACE_ME@$ESCAPED_OBJ@g"
# 输出:value: "{\"val1\": \"a\", \"val2\": \"b\"}"

GitHub工作流中的适配写法

直接在工作流里使用:

TEST_OBJECT='{"val1": "a", "val2": "b"}'
ESCAPED_OBJ="$(echo "$TEST_OBJECT" | sed 's/"/\\\\"/g')"
sed "s@_REPLACE_ME@$ESCAPED_OBJ@g" input.yml > ${{ github.action_path }}/config/job.yml

这样替换后的YAML文件里,value字段会保留正确的转义双引号,不会破坏YAML结构。


内容的提问来源于stack exchange,提问作者KungWaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 17:50:22