4

I have data like this

{
  "dateCreated": "2020-06-12",
  "status": "pending",
  "depositDate": "2020-06-15",
  "amount": 41237
}
{
  "dateCreated": "2020-06-05",
  "status": "paid",
  "depositDate": "2020-06-08",
  "amount": 37839
}
{
  "dateCreated": "2020-04-02",
  "status": "paid",
  "depositDate": "2020-04-03",
  "amount": 67
}

that's being formatted with jq like so:

 request-some-api | jq '.data[] | {dateCreated: .created | strftime("%Y-%m-%d"), status: .status, depositDate: .arrival_date | strftime("%Y-%m-%d"), amount: .amount,}'

and I'd like to modify the .amount so that it displays values rather than the number of cents as a dollar amount with a decimal place...

{
  "dateCreated": "2020-06-12",
  "status": "pending",
  "depositDate": "2020-06-15",
  "amount": $412.37
}
{
  "dateCreated": "2020-06-05",
  "status": "paid",
  "depositDate": "2020-06-08",
  "amount": $378.39
}
{
  "dateCreated": "2020-04-02",
  "status": "paid",
  "depositDate": "2020-04-03",
  "amount": $.67
}

...but I haven't found any documentation about this? Is jq able to do this conversion? Even without the $ sign but just adding the . between dollars and cents would be helpful.

5

Like this:

jq '.amount = "$" + (.amount/100|tostring)' file.json

Output

{
  "dateCreated": "2020-06-12",
  "status": "pending",
  "depositDate": "2020-06-15",
  "amount": "$412.37"
}
{
  "dateCreated": "2020-06-05",
  "status": "paid",
  "depositDate": "2020-06-08",
  "amount": "$378.39"
}
{
  "dateCreated": "2020-04-02",
  "status": "paid",
  "depositDate": "2020-04-03",
  "amount": "$0.67"
}
4
  • yes, to clarify, the solution in my case changes the end of my command from amount: .amount}' to amount: .amount} | .amount = "$" + (.amount/100|tostring)'.
    – alec
    Jun 12 '20 at 16:33
  • Note edge cases, if the amount ends in 0 or 00; the formatting won't be consistent. Dunno if that's a concern for this use case. Jun 12 '20 at 17:11
  • You should ask this to OP Jun 12 '20 at 17:12
  • 2
    You can use string interpolation to avoid the explicit call to tostring, and use |=: '.amount |= "$\(./100)"'
    – chepner
    Jun 13 '20 at 13:08
5

Your required output looks malformed; I'd expect "amount" to become a string value.

You can do this by adding a $ to the beginning, then dividing the amount by 100 and converting to a string

eg

jq '.amount = "$" + (.amount/100|tostring)'

Doing that on your test file we can see the 3 amount lines get converted to:

"amount": "$412.37"
"amount": "$378.39"
"amount": "$0.67"

However this has a couple of odd cases, which may (or may not) matter. If the amount ends in zero (eg 41230) then it will display as "$412.3". Similarly if it's whole dollars (41200) then it'll display was "$412".

I'm not sure jq has a simple way of handling these so I added a couple of tests:

jq '.amount = "$" + (.amount/100|tostring) + (if .amount%100 == 0 then ".0" else "" end ) + (if .amount%10 ==0 then "0" else "" end)'

There may be a more efficient way.

4
$ jq '.amount |= "$" + (./100 | tostring | ltrimstr("0"))' file
{
  "dateCreated": "2020-06-12",
  "status": "pending",
  "depositDate": "2020-06-15",
  "amount": "$412.37"
}
{
  "dateCreated": "2020-06-05",
  "status": "paid",
  "depositDate": "2020-06-08",
  "amount": "$378.39"
}
{
  "dateCreated": "2020-04-02",
  "status": "paid",
  "depositDate": "2020-04-03",
  "amount": "$.67"
}

This converts the amount key's value to a string after dividing it by 100. It then trims off the leading zero if present before prepending a $ to the string.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.