使用jq串行解析和显示json中的多个字段

San*_*San 188 json jq

我有这个Json

{
    "users": [
        {
            "first": "Stevie",
            "last": "Wonder"
        },
        {
            "first": "Michael",
            "last": "Jackson"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

使用jq我想连续显示名字和姓氏.像这样 -

Stevie Wonder
Michael Jackson
Run Code Online (Sandbox Code Playgroud)

这是我走了多远 -

jq '.users[].first, .users[].last'
Run Code Online (Sandbox Code Playgroud)

但它显示出来

"Stevie"
"Michael"
"Wonder"
"Jackson"
Run Code Online (Sandbox Code Playgroud)

请注意以下事项 -

  1. 我不想要的双引号.
  2. 我不想要的回车.
  3. 它混乱了.我的查询首先显示所有名字,然后显示所有姓氏.但是,我想要第一个,最后一对.

Eri*_*ord 284

我建议使用String Interpolation:

jq '.users[] | "\(.first) \(.last)"'
Run Code Online (Sandbox Code Playgroud)

参考

  • 对语法的解释将使这个答案更有用。 (10认同)
  • 如果您的数据是数字,这会好得多 (9认同)
  • 如果您不希望输出用引号引起来,请添加“-r”开关。 (6认同)
  • 一个好的答案不应该只是在链接中提供解释。链接的网站可能会发生任何事情,然后人们只能复制他们不理解的代码。 (3认同)
  • https://stedolan.github.io/jq/manual/#Stringinterpolation-%5C%28foo%29 (2认同)

abr*_*ham 161

您可以使用addition来连接字符串.

通过被结合成一个较大的字符串添加.

jq '.users[] | .first + " " + .last'
Run Code Online (Sandbox Code Playgroud)

  • 要消除JSON引号,请使用-r选项调用jq,例如jq -r'.users [] | .first +""+ .last' (33认同)
  • @Synesso:`(.numA | tostring)+""+(.numB | tostring)`应该有效.或者使用字符串插值:`"\(.numA)\(.numB)"`. (9认同)
  • +1,但对于我的用例,我正在尝试将两个数字格式化到同一行.这种方法失败了,因为它不能将"""添加到数字中.Eric的回答为这个案例提供了更好的结果. (2认同)

ing*_*net 75

除了其他人的建议之外,我认为还有两个选择值得一提。

打印为 CSV/TSV

$ cat file.json | jq -r '.users[] | [.first, .last] | @tsv'
Stevie  Wonder
Michael Jackson
Run Code Online (Sandbox Code Playgroud)
cat file.json | jq -r '.users[] | [.first, .last] | @csv'
"Stevie","Wonder"
"Michael","Jackson"
Run Code Online (Sandbox Code Playgroud)

第一个表达式 ,.users[]从最外层数组中取消对象的嵌套,如问题中给出的代码所示。下一个表达式[.first, .last]为每个输入对象创建一个新的值数组,最终表达式使用内置函数@tsv@csv将所有输入数组分别打印为制表符分隔和逗号分隔的值。

打印为 JSON 值

同样,可以再次构造 JSON 值,如果您只想保留字段的子集,这会很有趣:

$ cat file.json | jq -c '.users[] | {first}'
{"first":"Stevie"}
{"first":"Michael"}
Run Code Online (Sandbox Code Playgroud)


小智 14

我的方法将是(您的 json 示例格式不正确.. 猜测那只是一个示例)

jq '.Front[] | [.Name,.Out,.In,.Groups] | join("|")'  front.json  > output.txt
Run Code Online (Sandbox Code Playgroud)

返回这样的东西

"new.domain.com-80|8.8.8.8|192.168.2.2:80|192.168.3.29:80 192.168.3.30:80"
"new.domain.com -443|8.8.8.8|192.168.2.2:443|192.168.3.29:443 192.168.3.30:443"
Run Code Online (Sandbox Code Playgroud)

并使用正则表达式 grep 输出。


mac*_*qcq 13

虽然上面的两个答案都很好,如果key,value是字符串,我有一种情况可以追加一个字符串和整数(jq错误使用上面的表达式)

要求:在json下面构建一个url

pradeep@seleniumframework>curl http://192.168.99.103:8500/v1/catalog/service/apache-443 | jq .[0]
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   251  100   251    0     0   155k      0 --:--:-- --:--:-- --:--:--  245k
{
  "Node": "myconsul",
  "Address": "192.168.99.103",
  "ServiceID": "4ce41e90ede4:compassionate_wozniak:443",
  "ServiceName": "apache-443",
  "ServiceTags": [],
  "ServiceAddress": "",
  "ServicePort": 1443,
  "ServiceEnableTagOverride": false,
  "CreateIndex": 45,
  "ModifyIndex": 45
}
Run Code Online (Sandbox Code Playgroud)

解:

curl http://192.168.99.103:8500/v1/catalog/service/apache-443 |
jq '.[0] | "http://" + .Address + ":" + "\(.ServicePort)"'
Run Code Online (Sandbox Code Playgroud)

  • @nymo:这不是逃避。`\(...)` 是字符串插值。在这里它将数字`.ServicePort` 转换为字符串。可以使用插值代替 `+` 符号来缩短此解决方案。 (2认同)

小智 10

jq '.users[]|.first,.last' | paste - -
Run Code Online (Sandbox Code Playgroud)


小智 6

这将产生一个名称数组

> jq '[ .users[] | (.first + " " + .last) ]' ~/test.json

[
  "Stevie Wonder",
  "Michael Jackson"
]
Run Code Online (Sandbox Code Playgroud)


Tho*_*ner 5

通过做这样的事情,我非常接近我想要的

cat my.json | jq '.my.prefix[] | .primary_key + ":", (.sub.prefix[] | "    - " + .sub_key)' | tr -d '"' 
Run Code Online (Sandbox Code Playgroud)

其输出与 yaml 足够接近,我通常可以将其导入其他工具而不会出现太大问题。(我仍在寻找一种方法来基本导出输入 json 的子集)

  • 在我的情况下,这种工作,只需删除 | tr -d '"' 最后添加 -r 选项到 jq。 (2认同)