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 / 问题 / 699392
Accepted
raylight
raylight
Asked: 2022-04-18 10:52:33 +0800 CST2022-04-18 10:52:33 +0800 CST 2022-04-18 10:52:33 +0800 CST

是否可以使用 jq 从管道创建 JSON 字符串?

  • 772

假设我使用该命令find "$HOME" -maxdepth 1 -type d,我得到以下结果:

/home/user/folder1
/home/user/folder2
/home/user/folder3
/home/user/folder4

我想jq在管道上使用并创建不同的 JSON 行,如下所示:

{ "path": "/home/user/folder1", "type":"directory"}
{ "path": "/home/user/folder2", "type":"directory"}
{ "path": "/home/user/folder3", "type":"directory"}
{ "path": "/home/user/folder4", "type":"directory"}

jq我希望通过避免将这个文件夹列表放在一个数组中并在循环中一个一个地创建它们来解决它。在伪代码中,这个想法是:

find "$HOME" -maxdepth 1 -type d | jq '.logic-to-create-json-strings'

有可能jq吗?

jq
  • 2 2 个回答
  • 833 Views

2 个回答

  • Voted
  1. Best Answer
    Kusalananda
    2022-04-18T11:37:45+08:002022-04-18T11:37:45+08:00

    此答案假定您的文件名(或您希望 JSON 编码的任何文本)是有效的 UTF-8。

    两种选择:

    不使用xargs:直接从with调用jq路径名作为位置参数。读取找到的路径名,并将它们作为表达式中的数组访问。对于每个路径名,创建一个 JSON 对象。find-exec--args$ARGS.positional[]jq

    find "$HOME" -maxdepth 1 -type d \
        -exec jq -n -c '$ARGS.positional[] as $path | { path: $path, type: "directory" }' --args {} +
    

    使用xargs:使用-print0withfind和-0withxargs将找到的路径名从findto安全传递xargs。该jq表达式与上述相同,只是路径名之间传递的方式find不同jq。

    find "$HOME" -maxdepth 1 -type d -print0 |
    xargs -0 jq -n -c '$ARGS.positional[] as $path | { path: $path, type: "directory" }' --args
    

    使用上述两种方法,jq将对找到的路径名进行编码,以便能够将它们表示为 JSON 字符串。


    要将行读取到您显示的一组对象中,您可以使用以下jq命令,该命令从其标准输入流中读取:

    jq -R -c '{ path: ., type: "directory" }'
    
    • 2
  2. Stéphane Chazelas
    2022-04-18T12:04:35+08:002022-04-18T12:04:35+08:00

    JSON 不能在其字符串中直接表示任意文件路径(它们是非零的字节序列),这些字符串是 UTF-8 编码字符的序列。另请注意,除非您find使用-print0.

    例如,文件路径可能是$'/home/St\xc3\xa9phane\nChazelas/ISO-8859-1/R\xe9sum\xe9'(这里使用ksh93-style$'...'表示法表示字节值),éUTF-8 编码为Stéphane,ISO-8859-1 编码为Résumé.

    除非您使用某种编码,否则 JSON 无法表示该文件路径。这可能是例如 URI 编码:

    { "path": "/home/St%C3%A9phane\nChazelas/ISO-8859-1/R%E9sum%E9" }
    

    另一种方法可能是将路径解释为好像它是 ISO-8859-1 编码的(或任何字节值都可以成为有效字符的任何单字节字符集¹):

    { "path": "/home/Stéphane\nChazelas/ISO-8859-1/Résumé" }
    

    jq对进行 URI 编码有一些支持,但不能为 AFAIK 提供非 UTF-8 输入。AFAIK,它也不支持编码转换。

    在 GNU 系统上,对于文件路径被认为是 ISO-8859-1 编码的第二种方法,您可以执行以下操作:

    find ~ -type d -print0 |
      iconv -f iso-8859-1 -t utf-8 |
      tr '\0\n' '\n\0' |
      jq -Rc '{"path":sub("\u0000";"\n"),"type":"directory"}'
    

    在我们上面的例子中给出了:

    {"path":"/home/Stéphane\nChazelas/ISO-8859-1/Résumé.pdf","type":"directory"}
    

    ¹ 尽管 iso-8859-1 特别是一个明显的选择,因为它的代码点与 Unicode 的代码点匹配。因此,例如,如果您的 json 字符串包含 U+00E9 字符,您就知道它对应于 0xE9 字节。您可以添加-a选项以jq将非 ASCII 字符表示为\uXXXX。

    • 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