Search code examples
bashjqunix-timestampstrftime

jq null unix timestamps parsing issue


I'm trying to parse a big json file which I receive using curl.

By following this answer I could parse the next file:

$ cat test.json 
{"items": [{"id": 110, "date1": 1590590723, "date2": 1590110000, "name": "somename"}]}

using the next command:

TZ=Europe/Kyiv jq -r '.[] | .[] | .name + "; " + (.date1|strftime("%B %d %Y %I:%M%p")) + "; " + (.date2|strftime("%B %d %Y %I:%M%p"))' test.json

Output is:

somename; May 27 2020 02:45PM; May 22 2020 01:13AM

But when I try to parse the next file using the same command:

$ cat test2.json 
{"items": [{"id": 110, "date1": 1590590723, "date2": null, "name": "somename"}]}

Output is:

jq: error (at test2.json:1): strftime/1 requires parsed datetime inputs

I could replace those null values using sed by some valid values before parsing. But maybe there is a better way to skip (ignore) those values, leaving nulls in output:

somename; May 27 2020 02:45PM; null

Solution

  • You could tweak your jq program so that it reads:

    def tod: if type=="number" then strftime("%B %d %Y %I:%M%p") else tostring end;
    
    .[] | .[] | .name + "; " + (.date1|tod) + "; " + (.date2|tod)
    

    An alternative would be:

    def tod: (tonumber? | strftime("%B %d %Y %I:%M%p")) // null;
    
    .[] | .[] | "\(.name); \(.date1|tod); \(.date2|tod)"