如何对输入进行 JSON 转义?

如何对输入进行 JSON 转义?

我正在尝试开发一个工具,用于通过 API 将数据发送到 github gist。问题是 github api 将要点content视为一行,所有转义序列都按字面写出,如下所示:

{
  "test.txt": {
    "filename": "test.txt",
    "type": "text/plain",
    "language": "Shell",
    "raw_url": "https://gist.githubusercontent.com/jessebutryn/5c8b2a95b4b016e2fa33edee294c732b/raw/474f72ad32c843c18e9a61a228a31df6b85a8da1/test.txt",
    "size": 96,
    "truncated": false,
    "content": "#!/bin/sh\n\n# comment\nfunc () {\n\tfor ((i=1;i<10;i++)); do\n\t\t:\n\tdone\n}\n\nprintf '%s\\n' Foo bar baz\n"
  }
}

该内容显示如下:

#!/bin/sh

# comment
func () {
    for ((i=1;i<10;i++)); do
        :
    done
}

printf '%s\n' Foo bar baz

需要将其转换为:

#!/bin/sh\n\n# comment\nfunc () {\n\tfor ((i=1;i<10;i++)); do\n\t\t:\n\tdone\n}\n\nprintf '%s\\n' Foo bar baz\n

有没有任何工具可以一次性完成此操作?如果没有,有谁知道如何使用sed标准 UNIX 工具来完成它?


注意:原始文本中的任何文字转义序列都需要进行转义,以防止 github 解释它们(但这将是一个次要问题,不一定需要在这个问题中解决,但如果有的话那就太好了) :

IE:

printf '%s\n' Foo bar baz

变成:

printf '%s\\n' Foo bar baz

答案1

jq -R -s '.' < datafile

这会将所有内容datafile作为字符串读取,然后让 jq 将其作为 JSON 字符串打印出来。它将为您提供一个带引号的字符串,适合直接用其中的内容替换到该模板中datafile。数据将被正确的 JSON 引用,仅包含RFC 7159 转义使用,并且将在一大行中,因为 JSON 不允许字符串文字跨越多行。


您还可以使用模板 JSON 文件在 jq 中组装整个文档,

jq --arg f "$(cat datafile)" '.["test.txt"].content = $f' < template.json

最新版本jq有一个--rawfile f datafile选项,您可以使用该选项将文件加载到字符串中,而不是使用命令替换;你也可以用-R --slurp --slurpfile t template.json datafile和交换东西t["test.txt"].content = .

答案2

我必须转义一些 JSON 以包含在其他 JSON 中,并且有一个非常简单的解决方案:

$ jq @json <<< '{"Hello": "World"}'
"{\"Hello\":\"World\"}"

答案3

如果您有一个现有的 JSON 文档,file.json并且您只想将内容插入到正确的位置,请使用jq,

jq --rawfile content test.txt '."test.txt".content |= $content' file.json

如果内容应该是 base64 编码的:

base64 test.txt | jq --rawfile content /dev/stdin '."test.txt".content |= $content' file.json

使用(近似和jo的输出中的元数据)从头开始构建 JSON :statfile

#!/bin/sh

gist_url='some url'
filename=test.txt

jo -p "$filename"="$( jo \
        filename="$filename" \
        type="$( file -b --mime-type "$filename" )" \
        language="$( file -b "$filename" )" \
        raw_url="$gist_url" \
        size="$( stat -c %s "$filename" )" \
        truncated=false \
        content=@"$filename" )"

根据您的 Unix调整stat和实用程序(以上使用 Linux 选项)。file

输出:

{
   "test.txt": {
      "filename": "test.txt",
      "type": "text/x-shellscript",
      "language": "POSIX shell script, ASCII text executable",
      "raw_url": "some url",
      "size": 108,
      "truncated": false,
      "content": "#!/bin/sh\n\n# comment\nfunc () {\n    for ((i=1;i<10;i++)); do\n        :\n    done\n}\n\nprintf '%s\\n' Foo bar baz"
   }
}

使用%"$filename"代替 来@"$filename"获取密钥的 base64 编码值content

{
   "test.txt": {
      "filename": "test.txt",
      "type": "text/x-shellscript",
      "language": "POSIX shell script, ASCII text executable",
      "raw_url": "some url",
      "size": 108,
      "truncated": false,
      "content": "IyEvYmluL3NoCgojIGNvbW1lbnQKZnVuYyAoKSB7CiAgICBmb3IgKChpPTE7aTwxMDtpKyspKTsgZG8KICAgICAgICA6CiAgICBkb25lCn0KCnByaW50ZiAnJXNcbicgRm9vIGJhciBiYXoK"
   }
}

相关内容