jq

Posted on | 913 words | ~2 mins
Linux

JSON格式的字符串是Web API最常见的返回格式。在使用API时,我们经常使用curl或者wget快速方便的调试API。如果API返回的是JSON,输出到控制台里会像下面这样。没有格式,很难阅读:

1$ curl https://localhost/v1/stores/00138 -H Authorization:MyAuthCode
2{"data":{"results":[{"create_datetime":"2019-09-27T11:34:26","delete_datetime":null,"id":1,"is_delete":false,"name":"00138","setting":{"update_datetime":"2019-09-27T11:34:38"},"store_id":"00138","update_datetime":"2019-09-27T11:34:26"}],"total":1}}

jq是一款Linux工具,可以将JSON字符串格式化后输出到控制台上。在Ubuntu上安装十分简单apt-get install jq。安装成功后,再次使用curl测试API,同时用管道连接到jq

 1$ curl https://localhost/v1/stores/00138 -H Authorization:MyAuthCode | jq .
 2{
 3    "data": {
 4        "results": [
 5        {
 6            "create_datetime": "2019-09-27T11:34:26",
 7            "delete_datetime": null,
 8            "id": 1,
 9            "is_delete": false,
10            "name": "00138",
11            "setting": {
12                "update_datetime": "2019-09-27T11:34:38"
13            },
14            "store_id": "00138",
15            "update_datetime": "2019-09-27T11:34:26"
16        }
17        ],
18        "total": 1
19    }
20}

是不是世界立刻清爽了?jq的强大远不止于此。如果只想查看results数组内的内容:

 1$ curl https://localhost/v1/stores/00138 -H Authorization:MyAuthCode | jq -r 'data.results'
 2[
 3    {
 4        "create_datetime": "2019-09-27T11:34:26",
 5        "delete_datetime": null,
 6        "id": 1,
 7        "is_delete": false,
 8        "name": "00138",
 9        "setting": {
10            "update_datetime": "2019-09-27T11:34:38"
11        },
12        "store_id": "00138",
13        "update_datetime": "2019-09-27T11:34:26"
14    }
15]

results是个数组,如果只想查看数组中第1个元素:

 1$ curl https://localhost/v1/stores/00138 -H Authorization:MyAuthCode | jq -r 'data.results[0]'
 2{
 3    "create_datetime": "2019-09-27T11:34:26",
 4    "delete_datetime": null,
 5    "id": 1,
 6    "is_delete": false,
 7    "name": "00138",
 8    "setting": {
 9        "update_datetime": "2019-09-27T11:34:38"
10    },
11    "store_id": "00138",
12    "update_datetime": "2019-09-27T11:34:26"
13}

请注意上面的输出不再有**[ ]**。如果只想输出数组中每个元素的id和name属性:

1$ curl https://localhost/v1/stores/00138 -H Authorization:MyAuthCode | jq -r 'data.results[]|.id,.name'
21
300138

将每个元素的id和name按顺序依次输出。每个属性单占一行。由于实例中results数组只有一个元素,故只输出了两行,分别对应id(1)和name(00138)。如果想将数组中每个元素转换为另一个字典输出,比如将id和name的属性值交换位置:

1$ curl https://localhost/v1/stores/00138 -H Authorization:MyAuthCode | jq -r 'data.results[]|{id:.name,name:.id}'
2{
3    "id": "00138",
4    "name": 1
5}

有了jq这款利器,我们开发的工具输出结果到控制台时,也可以用JSON格式。搭配jq可以漂亮展示结果,方便观察和调试。再无需操心如何用print到控制台才能看起来方便些。不过务必注意,工具输出时要格式化为 JSON字符串 ,而不是像下面这样:

1def foo():
2    json_obj = dict(a=1, b=1)
3    print(json_obj)

运行上述代码:

1$ python foo.py
2{'a': 1, 'b': 2}
3
4$ python foo.py | jq .
5parse error: Invalid numeric literal at line 1, column 5

因为{'a': 1, 'b': 2}不是一个合法的Json字符串。正确做法:

1def foo():
2    json_obj = dict(a=1, b=1)
3    print(json.dumps(json_obj))

再次运行:

1$ python foo.py
2{"a": 1, "b": 2}
3
4$ python foo.py | jq .
5{
6    "a": 1,
7    "b": 2
8}

此外,如果有从网页上拷贝下来的大JSON想用jq格式化一下,有两个方法:

  • 保存在一个临时文件json.txt,然后jq . json.txt
  • 也可以直接在控制台上输入echo '{"a": 1, "b": 2}' | jq .