【问题标题】:sed unterminated `s' command with jq json string带有 jq json 字符串的 sed 未终止的 `s' 命令
【发布时间】:2020-05-04 13:33:21
【问题描述】:

背负this question 我有一个命令(在 Docker 容器中运行),我试图用 sed 将表达式替换为 jq 生成的 JSON 字符串。

小故事:

我在文件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 的了解还不够,无法弄清楚如何修复它,我觉得我必须移动一些引号/分隔符,或者可能将我的 jq 通过管道传递给“清理” up" 替换之前的 json 字符串,但我不确定是什么。

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

【问题讨论】:

  • 与其努力让 sed 与 jq 一起工作,为什么不只使用 jq 来做所有事情呢?如果您对somefile 的外观进行一些说明,也许会有所帮助。
  • @peak 这是一个 HTML 文件,我用 JSON 字符串替换占位符。
  • 如果你的 jq 支持 --rawfile 命令行选项,那么使用 jq 来执行这两个任务会很容易。
  • @peak 那会是什么样子?

标签: json shell sed jq edit


【解决方案1】:

这有点棘手,因为替换字符串有很多行。你可以试试这个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

【讨论】:

  • 我不知道替换字符串有很多行,我认为它是“扁平的” - 我可以使用 jq 来缩小 JSON 输出以使 sed 上的事情更容易吗?
  • 同一命令,我试图将 jq 命令的输出通过管道传输到 ` | jq -c` 但我想我错过了什么
  • 好吧,即使是那个命令,即jq -nRc '[inputs | {(.): env[.]}] | add' tmp.txt,也可以很好地配合我建议的sed 命令。试试吧,让我知道。
  • -nRc 有效!我无意让我的替换字符串有很多行,现在我明白为什么 sed 会窒息了。非常感谢!
【解决方案2】:

@Adam 问:

那会是什么样子?

如果您的 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)'


【讨论】:

    猜你喜欢
    • 2016-07-29
    • 1970-01-01
    • 2019-05-04
    • 2016-03-10
    • 2013-06-11
    • 2012-05-05
    • 2012-07-10
    • 2013-11-27
    • 2018-05-29
    相关资源
    最近更新 更多