Search code examples
linuxshellcommand-linejq

Exploring json with command lines


Can someone helps me finding out a solution for this problem with a command line? Here's my Json file :

{
  "type": "record",
  "name": "ShelfEx »position,
  "fields": [
    {
      "name": "shopId",
      "type": {
        "type": "string",
        "avro.java.string": "String"
      },
      "doc": "Id of the shop"
    },
    {
      "name": "productId",
      "type": {
        "type": "string",
        "avro.java.string": "String"
      },
      "doc": "Id of the product"
    },
    {
      "name": "sourceId",
      "type": {
        "type": "string",
        "avro.java.string": "String"
      },
      "doc": "Id of the source"
    },
    {
      "name": "timestampTransmission",
      "type": "long",
      "doc": "Timestamp of the message"
    },
    {
      "name": "productQuantity",
      "type": [
        "null",
        "double"
      ],
      "doc": "Quantity of the product",
      "default": null
    }
  ]
}

and i want to get the name of each field, with it's type and eventually it's default value (null in the case of productQuantity). So the output should but something like :

"shopId" string
"productId" string
...
"timestampTransmission" long
"productQuantity" double null

Any idea please?

`cat file.json | jq -r '.fields[] | "\"\(.name)\" : \(.type | tostring | sub("^(null)$"; "\\1 :     null") | sub("(^\"|\"$)"; ""))"'`

Instead of :

"shopId" string
"productId" string
...
"timestampTransmission" long
"productQuantity" double null

i had :

"shopId" : {"type":"string","avro.java.string":"String"}
"productId" : {"type":"string","avro.java.string":"String"}
"sourceId" : {"type":"string","avro.java.string":"String"}
"timestampTransmission" : long
"productQuantity" : ["null","double"]

Solution

  • If I correctly understand your formatting, you want

    .fields[] | [
    
      # .name in quotes (what about escaping?)
      "\"\(.name)\"",
    
      # .type.type or .type[] or .type as a scalar, filtering out null
      (.type | objects.type // arrays[] // . | select(. != "null")),
    
      # .default, only if it exists
      (select(has("default")).default | tostring)
    
    ] | join(" ")
    

    Use it as jq -r '…' file.json to get

    "shopId" string
    "productId" string
    "sourceId" string
    "timestampTransmission" long
    "productQuantity" double null
    

    Demo