How to pad numbers with JQ?

3.4k views Asked by At

I'd like to add leading/trailing zeros to strings from numbers — resultant string needs to contain "01" or "001" and not "1". I noticed project https://github.com/joelpurra/jq-zeros but I have jq installed from package manager (dnf, fedora) so requirement of some jqnpm is not feasible for me (at first sight), not to mention my fear of npm, as stuff sudo npm -g ruined my system several times already.

Question:

  1. these package managers for jq, are they even in process of being accepted into mainstream or not?
  2. the padding itself — how to do it without this extra library?
4

There are 4 answers

0
customcommander On BEST ANSWER

Given this JSON document:

7

You can achieve "007" with the following filter: (or "042" with 42)

tostring | (length | if . >= 3 then "" else "0" * (3 - .) end) as $padding | "\($padding)\(.)"
  1. tostring convert 7 into "7"
  2. If number had 3 or more digits then set padding to "" otherwise set to "0" * (3 - length). (When a string is multiplied by a number it is repeated that many time e.g. "foo" * 3 -> "foofoofoo")
  3. And append the number to the end
0
peak On

Based on the jq-esque definition from In jq, how to get tonumber to output decimal instead of scientific notation :

def lpad(n):
  tostring
  | if (n > length) then ((n - length) * "0") + . else . end;

As for jq module managers, there is nothing in jq’s official development pipeline, but jqnpm has nothing to do with npm, and is pretty safe to use, at least if you don’t run it with sudo.

0
Jeff Mercado On

You could define these functions at the start of your filter or adding it to your ~/.jq file then use it to pad the numbers.

def pad_left($len; $chr):
    (tostring | length) as $l
    | "\($chr * ([$len - $l, 0] | max) // "")\(.)"
    ;
def pad_left($len):
    pad_left($len; " ")
    ;

Then to use it to pad your value with three 0s:

pad_left(3; "0")
0
Luiz Angelo Daros de Luca On

If you are sure the number will not overflow the format digits, you can simulate a "%03d" with:

aNumber+1000|tostring[1:]