jq 是一款命令行的 json 处理工具。类似于 lodash 一样,它可以对 json 做各种各样的处理: pickgetfiltersortmap
由于 jq 本身比较简单,以下总结一些经常用到的示例。如果需要更多的细节,可以参考 jq 官方文档(opens new window)
先创建一个样例 demo.jsonljsonl 即每行都是一个 json,常用在日志格式中

  1. {"name": "shanyue", "age": 24, "friend": {"name": "shuifeng"}}
  2. {"name": "shuifeng", "age": 25, "friend": {"name": "shanyue"}}

由于在后端 API 中会是以 json 的格式返回,再次创建一个样例 demo.json

  1. [
  2. {"name": "shanyue", "age": 24, "friend": {"name": "shuifeng"}},
  3. {"name": "shuifeng", "age": 25, "friend": {"name": "shanyue"}}
  4. ]

jq 命令详解

jq 主要可以分作两部分,options 即选项,filter 即各种转换操作,类似于 lodash 的各种函数

  1. jq [options...] filter [files]

强烈建议参考 jq 官方手册 (opens new window),命令示例一应俱全

option

我仅常用以下几个选项

  • -s: 把读取的 jsonl 视作数组来处理 (如 group, sort 只能以数组作为输入)
  • -c: 不对输出的 json 做格式化,一行输出

    filter

    filter 各种转换操作就很多了,如 getmapfiltermappickuniqgroup 等操作

  • .: 代表自身

  • .a.b: 相当于 _.get(input, 'a.b')
  • select(bool): 相当于 _.filter(boolFn)
  • map_values: 相当于 _.map,不过 jq 无法单独操作 key
  • sort
  • group_by

    更多 filter 参考 jq 官方手册(opens new window)

jq examples

虽然 jq 的功能很强大,但平时使用最为频繁的也就以下几个示例。当然复杂的情形也会有,参考我过去一篇使用 jqts 类型错误的一篇文章: sequelize 升级记录(opens new window)

json to jsonl

  1. $ cat demo.json | jq '.[]'
  2. {
  3. "name": "shanyue",
  4. "age": 24,
  5. "friend": {
  6. "name": "shuifeng"
  7. }
  8. }
  9. {
  10. "name": "shuifeng",
  11. "age": 25,
  12. "friend": {
  13. "name": "shanyue"
  14. }
  15. }

jsonl to json

  1. # -s: 代表把 jsonl 组成数组处理
  2. $ cat demo.jsonl | jq -s '.'
  3. [
  4. {
  5. "name": "shanyue",
  6. "age": 24,
  7. "friend": {
  8. "name": "shuifeng"
  9. }
  10. },
  11. {
  12. "name": "shuifeng",
  13. "age": 25,
  14. "friend": {
  15. "name": "shanyue"
  16. }
  17. }
  18. ]

. (_.get)

  1. $ cat demo.jsonl | jq '.name'
  2. "shanyue"
  3. "shuifeng"

{} (_.pick)

  1. $ cat demo.jsonl| jq '{name, friendname: .friend.name}'
  2. {
  3. "name": "shanyue",
  4. "friendname": "shuifeng"
  5. }
  6. {
  7. "name": "shuifeng",
  8. "friendname": "shanyue"
  9. }

select (_.filter)

  1. $ cat demo.jsonl| jq 'select(.age > 24) | {name}'
  2. {
  3. "name": "shuifeng"
  4. }

mapvalues (.map)

  1. $ cat demo.jsonl| jq '{age} | map_values(.+10)'
  2. {
  3. "age": 34
  4. }
  5. {
  6. "age": 35
  7. }

sortby (.sortBy)

sort_by 需要先把 jsonl 转化为 json 才能进行

  1. # 按照 age 降序排列
  2. # -s: jsonl to json
  3. # -.age: 降序
  4. # .[]: json to jsonl
  5. # {}: pick
  6. $ cat demo.jsonl | jq -s '. | sort_by(-.age) | .[] | {name, age}'
  7. {
  8. "name": "shuifeng",
  9. "age": 25
  10. }
  11. {
  12. "name": "shanyue",
  13. "age": 24
  14. }
  15. # 按照 age 升序排列
  16. $ cat demo.jsonl | jq -s '. | sort_by(.age) | .[] | {name, age}'
  17. {
  18. "name": "shanyue",
  19. "age": 24
  20. }
  21. {
  22. "name": "shuifeng",
  23. "age": 25
  24. }