AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 737018
Accepted
YourMJK
YourMJK
Asked: 2023-02-27 03:36:52 +0800 CST2023-02-27 03:36:52 +0800 CST 2023-02-27 03:36:52 +0800 CST

使用 jq 在 JSON 字符串值中保留转义的正斜杠

  • 772

根据 JSON 规范,正斜杠不必用反斜杠转义,但可以。
我有一个 JSON 文件,其中出于兼容原因(但不在键内)转义了字符串值中的所有正斜杠:

{
  "proto://some/path": "\/\/some\/path"
}

但是,jq自动删除这些反斜杠:

$ echo '{"proto://some/path":"\/\/some\/path"}' | jq -c .
{"proto://some/path":"//some/path"}

我需要输出是{"proto://some/path":"\/\/some\/path"}

我怎么知道jq不要更改任何字符串值并保留这些反斜杠?或者,有没有办法在它通过后将
这些反斜杠仅重新添加到值中jq?

jq
  • 2 2 个回答
  • 300 Views

2 个回答

  • Voted
  1. Best Answer
    Stéphane Chazelas
    2023-02-27T04:12:25+08:002023-02-27T04:12:25+08:00

    如果你能的话,我会感到惊讶。jq解码其输入,执行其操作并将结果对象编码为 json。\编码输出时,输出的是那些JSON编码的字符串, s前面有s的信息/早就丢失了。如果那些/最初写的 s也会发生同样的情况\u002f。您会发现出于同样的原因,它jq也会重新格式化1.0为1、1e2as 100、INFas等。1.7976931348623157e+308

    然而,JSON 是一种相对容易的文件格式,可以使用例如 perl 正则表达式手动可靠地处理。

    要在除对象键之外的所有字符串中的\每个字符串之前添加s,您可以执行以下操作:/

    jq... |
      perl -0777 -pe '
        s{"(?:\\.|.)*?"(\s*:)?}{
          $1 ? $& : $& =~ s{/}{\\/}gr
        }ge'
    

    即使您有嵌入"s 和\s 的字符串(如{"key": "//\"//\\"}),它也应该可以正常工作。

    作为 的替代方案jq,您可以使用 JSON::PPperl模块,它可以被告知转义斜杠(尽管会出现在所有字符串中):

    $ json_pp -json_opt escape_slash < your-file
    {"proto:\/\/some\/path":"\/\/some\/path"}
    

    如果您已经熟悉perl,那么学习曲线就不会比必须学习jq语法那么陡峭。

    在任何情况下,虽然 JSON 格式允许/将 s 转义为\/(或\u002f像任何字符一样)那些不需要的。根据我在网上阅读的内容,这是允许的,因此可以通过编写将包含</在 HTML标记中的 JSON 字符串嵌入. 这就是为什么一些 JSON 编码器将它们编码为更便携的原因。但是,如果该 JSON 不打算像在 HTML 中那样嵌入,那么它可能并不重要。如果是这样,您可能希望在任何地方都使用该编码,包括在对象键中。<script>"<\/whatever"\//

    • 3
  2. Kusalananda
    2023-02-27T04:13:37+08:002023-02-27T04:13:37+08:00

    我假设一些不知道需要在 JSON 中编码字符串的进程已经插入了他们认为需要存储的文字字符串,但没有对其进行编码。jq由于反斜杠是不需要转义的转义字符,并且由于没有反斜杠本身对文字反斜杠进行转义,因此当用于提取和解码字符串或出于其他原因处理文档时,它们将看起来“消失” 。

    简而言之,正斜杠不必转义(转义它们实际上是一个空操作),但如果你想将它们保留为文字反斜杠,则反斜杠需要转义。

    以下将递归地将文档中所有字符串值中的每个更改/为\\/(这是您在 JSON 字符串中的写入方式)。\/请记住,当jq表达式处理数据时,jq解析器已经删除了反斜杠。

    jq 'walk(if type == "string" then gsub("/"; "\\/") else . end)' file
    

    对于给定的示例文档,这将生成

    {
      "proto://some/path": "\\/\\/some\\/path"
    }
    

    从修改后的文档中提取和解码编码字符串值将为您提供\/\/some\/path:

    $ jq 'walk(if type == "string" then gsub("/"; "\\/") else . end)' file | jq -r '."proto://some/path"'
    \/\/some\/path
    

    如果您像这样从头开始创建它,您将得到相同的 JSON 文档:

    $ jq -n --arg 'proto://some/path' '\/\/some\/path' '$ARGS.named'
    {
      "proto://some/path": "\\/\\/some\\/path"
    }
    
    • 2

相关问题

  • 使用 jq 获取结构化输出

  • 如何将嵌入(引用)的 json 字符串转换为 json

  • JSON数组使用jq来bash变量

  • jq 打印子对象中所有的键和值

  • jq 使用多个 --arg 添加或更新一个值

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve