简体   繁体   中英

How to pretty print using jq, so that multiple values are on the same line?

What I get from jq is:

{
  "frameGrid": {
    "size": [
      24,
      24
    ],
    "dimensions": [
      1,
      1
    ],
    "names": [
      [
        "default"
      ]
    ]
  }
}

What I would like to see is something more like this:

{
  "frameGrid": {
    "size": [24,24], 
    "dimensions": [1,1],
    "names": [["default"]]
  }
}

I know both forms are valid, and that jq has a compact/pretty print mode. But is there something in-between? I'm looking to somehow format a larger json file that has many more array values than this, so that it's easily readable and printable. Maybe I'm just using the wrong tool for this job?

(please excuse the horrid formating choice. Seems code-sample doesn't like json formats much)

While it is probably best to use a tool like the one peak suggested if your json isn't too complex you could use a second jq invocation to postprocess the output of the first. For example if your data is in data.json

$ jq -M . data.json | jq -MRsr 'gsub("\n      +";"")|gsub("\n    ]";"]")'

produces

{
  "frameGrid": {
    "size": [24,24],
    "dimensions": [1,1],
    "names": [["default"]]
  }
}

As @jq170727 mentioned, postprocessing after a pretty-printing run of jq (eg jq . ) is worth considering. In that vein, here is an awk script that might suffice:

#!/bin/bash

awk '
  function ltrim(x) { sub(/^[ \t]*/, "", x); return x; }
  s && NF > 1 && $NF == "["  { s=s $0;               next}
  s && NF == 1 && $1 == "]," { print s "],";   s=""; next}
  s && NF == 1 && $1 == "["  { print s;        s=$0; next}
  s && NF == 1 && $1 == "{"  { print s; print; s=""; next}
  s && NF == 1 && $1 == "]"  { print s $1;     s=""; next}
  s && NF == 1 && $1 == "}"  { print s;        s=$0; next}
  s                          { s=s ltrim($0);        next}
  $NF == "["                 { s=$0;                 next}
  {print}
'

Examples

With the example input, the invocation:

 jq . example.json | ./pp

produces:

{
  "frameGrid": {
    "size": [24,24],
    "dimensions": [1,1],
    "names": [
      ["default"]
    ]
  }
}

The invocation:

jq -n '{a:[1,2,3,[1,2,3,4]],b:2,c:{d:[1,2,{e:[3,4]}]}}' | ./pp

produces:

{
  "a": [1,2,3,
    [1,2,3,4]
  ],
  "b": 2,
  "c": {
    "d": [1,2,
      {
        "e": [3,4]
      }
    ]
  }
}

If you're not married to jq, take a look at FracturedJson . There's a web-based formatter, a commandline app, and a couple libraries.

FracturedJson inlines arrays/objects as long as they're neither too long nor too complex (according to your settings). It can also do arrays as multiple lines with multiple items per line, again, if they're not too complex. Otherwise it breaks things out in the classic indented form.

Here's the data from the original question using the default settings:

{
    "frameGrid": {
        "size": [24, 24],
        "dimensions": [1, 1],
        "names": [ ["default"] ]
    }
}

Disclosure: I'm the author of FracturedJson. It's open source under an MIT license.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM