Use jq to Format Certain Fields as Compact?

元气小坏坏 提交于 2019-12-02 05:04:38

A constrained-width JSON pretty-printer could be written in jq itself. Here is a pretty-printer which illustrates how this could be done, though in its present incarnation, it is of limited usefulness.

ppArray(indent; incr; width) will emit a stream of JSON strings that together are equivalent to the tostring value of the input. For robustness, it will always act as a pretty-printer, even if the width restriction is violated.

If the input is an array, and if none of its elements (or recursively their elements) contains any large objects or long strings, then assuming the values of the parameters are reasonably chosen and that nesting is not too deep relative to these parameters, each emitted string should be no longer than "width".

# indent is the initial indentation level;
# incr is the number of spaces to add for one additional indentation level;
# width is the target maximum width.
#
def ppArray(indent; incr; width):
  # The inner function produces an array of unindented strings.
  def ppArray_(incr_; width_):
    tostring as $tostring
    | if $tostring|length <= (width_ - incr_) then [$tostring]
      else reduce .[] as $i
        ([];  
         ($i|tostring) as $is
          | if length == 0 then [ $is ]
            else .[-1] as $s
            | ($s|length) as $n
            | ($is|length) as $isl
            | if $n + $isl <= (width_ - incr_)
             then .[-1] = ($s + ", " + $is)
              elif ($i|type) == "array"
             then (.[-1]+=",") + [ $i | ppArray(0; incr_; width_ - incr_) ]
              else  (.[-1]+=",") + [ $is ]
              end 
            end )
      end;

    (" " * indent) as $indentation
    | if type == "array" 
      then ppArray_(incr; width - indent)
           | $indentation + "[",
           (.[] | ($indentation + "  " + . )),
           $indentation + "]"
    else $indentation + tostring
    end
;

Example:

[range(0;16)]
|
(ppArray(0; 2; 10)),
"::",
([{a:1}, {b:2}, {c:3}]  | ppArray(0; 2; 10)),
"::",
(.[2]=[range(0;10)]) | ppArray(0; 2; 10)

Invocation:

jq -nrf pp.jq

Output:

[
  0, 1, 2, 3,
  4, 5, 6, 7,
  8, 9, 10,
  11, 12, 13,
  14, 15
]
::
[
  {"a":1},
  {"b":2},
  {"c":3}
]
::
[
  0, 1,
  [
    0, 1, 2,
    3, 4, 5,
    6, 7, 8,
    9
  ], 3, 4, 5,
  6, 7, 8, 9,
  10, 11, 12,
  13, 14, 15
]
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!