带有 jq json 字符串的 sed 未终止的 `s' 命令

sed unterminated `s' command with jq json string

搭载 我有一个命令(运行 在 Docker 容器中),我在其中尝试 sed 以用 JSON 字符串替换表达式由 jq.

生成

小小的背景故事:

我在文件中有一个环境变量白名单 tmp.txt:

ENV_VAR_A
ENV_VAR_B
ENV_VAR_C

我使用 jq 使用上一个线程中的答案生成一个 JSON 字符串,如下所示:

jq -Rn '[inputs | {(.): env[.]}] | add' ./tmp.txt
# GENERATES { "ENV_VAR_A": "a val", "ENV_VAR_B": "a val", "ENV_VAR_C": "a val"}

太棒了!现在我正在尝试使用 sed(作为 Docker CMD)来替换某些东西:

# CMD sed -i 's@{{SOME_PATTERN}}@'$( jq -Rn '[inputs | {(.): env[.]}] | add' ./etc/nginx/conf.d/env)'@' ./somefile

但我得到:

sed: -e expression #1, char 22: unterminated `s' command

所以替换出了问题 - 但我对 shell 的了解还不够,无法弄清楚如何修复它,我觉得我必须移动一些 quotes/delimiters,或者也许在替换之前将我的 jq 通过管道传输到 "clean up" json 字符串,但我不确定是什么。

正在寻找一些 sed-fu,有人可以帮忙吗?

这有点棘手,因为替换字符串有很多行。您可以尝试使用进程替换 sed

sed -i -e '/{{SOME_PATTERN}}/r '<( jq -Rn '[inputs | {(.): env[.]}] | add' /etc/nginx/conf.d/env) -e '//d' somefile

确保您使用的是 bash

对生成单行输出的 jq 命令稍作修改,您只需执行以下操作:

sed -i 's/{{SOME_PATTERN}}/'"$(jq -nRc '[inputs | {(.): env[.]}] | add' /etc/nginx/conf.d/env)"'/' somefile

@亚当问:

what would that look like?

如果您的 jq 具有 --rawfile 选项,则无需兼顾 jq 和 sed:

< somefile jq -R --rawfile text tmp.txt '
  ($text
   | split("\n")
   | map(select(length>0)
   | {(.): env[.]}) | add) as $json
  | sub("{{SOME_PATTERN}}"; $json|tostring)'