【问题标题】:Extract JSON value to shell variable using jq使用 jq 将 JSON 值提取到 shell 变量
【发布时间】:2017-07-08 00:14:57
【问题描述】:

我有一个如下所示的 json 响应:

[
 {"id":10,
 "list_file":["/var/a.txt",
             "/dev/b.txt"]}
]

我需要提取 list_file 的值并将它的 shell 变量存储为一个数组。我尝试循环并读取值。

#!/bin/bash
x=()
while read -r value
do
  #echo "$value"
  x+=("$value")
done < <(jq -r '.[] | .list_file' input.json)

但数组中提取的值也包含引号、括号和逗号。

[
    "/var/a.txt",
    "/dev/b.txt"
]

您能否帮我修改代码,使数组只包含条目/var/a.txt 和/dev/b.txt。另外,我尝试了 readarray 和 map,但它们在 Mac Osx 上不起作用。任何帮助将不胜感激。

【问题讨论】:

  • 这不是有效的 json,请您修复您的示例(editting 问题)
  • 更正了 json。

标签: json bash shell jq


【解决方案1】:

为了正确处理所有值,您需要使用declare 命令将jq 的输出合并到一个数组赋值中。

这里有一些输入需要担心一些极端情况:空格、换行符和全局字符。

$ cat input.json
[
    {"id":10,
    "list_file":[
        "/var/a b.txt",
        "/dev/c\nd.txt",
        "*"]}
]

jq 命令提取并输出正确引用的字符串以供 shell 使用:

$ $ jq -r '.[] | .list_file[] | @sh' input.json
'/var/a b.txt'
'/dev/c
d.txt'
'*'

还有一个可以利用输出的 shell 命令:

$ declare -a "x=($(jq -r '.[] | .list_file[] | @sh' input.json))"

证明它工作正常:

$ printf '==%s==\n' "${x[@]}"
==/var/a b.txt==
==/dev/c
d.txt==
==*==

【讨论】:

  • 谢谢!谷歌这个答案很好,微妙和棘手。
【解决方案2】:

您可以将@tsv 字符串格式化程序与--raw-output/-r 选项结合使用,并将输出拆分为选项卡上的bash 数组:

$ IFS=$'\t'
$ x=($(jq -r '.[] | .list_file | @tsv' input.json))
$ for xx in "${x[@]}"; do echo "$xx"; done
/var/a.txt
/dev/b.txt

对于-r 将去除外部引号(用于使jq 过滤器与非基于JSON 的系统对话),@tsv 将输出一个数组作为一系列制表符分隔的字符串(制表符、换行符等将被转义)。

或者,您使用@sh 过滤器将数组输出为一系列以空格分隔的字符串。然而,要解释这样的输出,你必须evaluate 它:

$ eval "x=($(jq -r '.[] | .list_file | @sh' input.json))"

【讨论】:

  • 能否请您告诉我如何去掉引号,因为我必须遍历指定的路径并处理文件。
  • 这并不完全正确。输出是带引号的,但 shell 本身不会在这种情况下将引号视为语法引号;尝试使用 list_file 中包含空格的文件名。
【解决方案3】:
    1234563 while read -r value 逐行读取值的技术。 (这些面向行的方法的一个优点是无需摆弄 IFS。)
  1. 对于手头的问题,在某些情况下,保留特殊字符的 JSON 表示可能会更好,例如“\n”表示 NEWLINE,“\u0000”表示 NUL 等。率,使用-r 的通用替代方法是使用-c 命令行选项,如下所示:

$ readarray -t x < <(jq -n -c '("\u0001\nb", "c\td", "e\u0000f")'
  | sed -e 's/^\"//' -e 's/\"$//' )
$ printf ":%s:\n" "${x[@]}"
:\u0001\nb:
:c\td:
:e\u0000f:

【讨论】:

    猜你喜欢
    • 2019-02-15
    • 2018-11-02
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 2022-11-15
    • 2019-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多