使用jq顺序解析和显示json中的多个字段


237

我有这个杰森

{
    "users": [
        {
            "first": "Stevie",
            "last": "Wonder"
        },
        {
            "first": "Michael",
            "last": "Jackson"
        }
    ]
}

我想使用jq顺序显示名字和姓氏。像这样-

Stevie Wonder
Michael Jackson

这就是我所走的路-

jq '.users[].first, .users[].last'

但它显示

"Stevie"
"Michael"
"Wonder"
"Jackson"

请注意以下内容-

  1. 我不希望使用双引号。
  2. 我不要的回车。
  3. 混乱了。我的查询将首先显示所有名字,然后显示所有姓氏。但是,我想要倒数第一。

Answers:



203

您可以使用additional连接字符串。

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

jq '.users[] | .first + " " + .last'

firstlast均为字符串时,上述方法适用。如果要提取不同的数据类型(数字和字符串),那么我们需要转换为等效的类型。参照对这个问题的解决方案。例如。

jq '.users[] | .first + " " + (.number|tostring)'

41
要消除JSON引号,请使用-r选项调用jq,例如jq -r'.users [] | .first +“” + .last'–
高峰,

4
+1,但对于我的用例,我正在尝试将两个数字格式化为同一行。此方法失败,因为它不能" "加到数字上。对于这种情况,Eric的答案给出了更好的结果。
Synesso,2015年

9
@Synesso:(.numA|tostring) + " " + (.numB|tostring)应该可以。或改为使用字符串插值:"\(.numA) \(.numB)"
LS

当我做了jq '.users[] | .first + " " + .last',效果很不错,但造成的值之间的换行.first.last。我改变了" ""@",然后做一个sed 's/@/ /g'在输出端得到“约翰·史密斯”作为输出。像这样的东西:jq '.users[] | .first + "@" + .last' | sed 's/@/ /g'
Bloodysock


14

如果key,value是字符串,上述两个答案都可以很好地工作,但我有一种情况要附加字符串和整数(使用上述表达式的jq错误)

要求:在json下面构造一个网址

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
}

解:

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

请注意,转义括号是不需要的,并且会出错。
nymo

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

12

这将产生一个名称数组

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

[
  "Stevie Wonder",
  "Michael Jackson"
]

4

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

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

对于我来说,它的输出与yaml足够接近,因此通常可以毫无问题地将其导入其他工具。(我仍在寻找一种方法来基本导出输入json的子集)


1
就我而言,这种工作方式只是将| tr -d'“'结尾,并在jq中添加-r选项
。– user842479

4

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

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

返回这样的东西

"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"

并用正则表达式grep输出。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.