Search code examples
jsonexport-to-csvjq

Use JQ to parse JSON array of objects, using select to match specified key-value in the object element, then convert to CSV


Use JQ to parse JSON array of objects, using select to match specified key-value in the object element, then convert to CSV.

Data Source:

{
  "Other": [],
  "Objects": [
    {
      "ObjectElementName": "Test 123",
      "ObjectElementArray": [],
      "ObjectElementUnit": "1"
    },
    {
      "ObjectElementName": "Test ABC 1",
      "ObjectElementArray": [],
      "ObjectElementUnit": "2"
    },
    {
      "ObjectElementName": "Test ABC 2",
      "ObjectElementArray": [],
      "ObjectElementUnit": "5"
    }
  ],
  "Language": "en-US"
}

JQ command to extract

jq -r '.Objects[] | select(.ObjectElementName | contains("ABC"))'

Output given (individual objects only, no JSON structure)...

{
  "ObjectElementName": "Test ABC 1",
  "ObjectElementArray": [],
  "ObjectElementUnit": "2"
}
{
  "ObjectElementName": "Test ABC 2",
  "ObjectElementArray": [],
  "ObjectElementUnit": "5"
}

Output needed in this format (preserving the JSON array above the objects)

{
  "Other": [],
  "Objects": [
    {
      "ObjectElementName": "Test ABC 1",
      "ObjectElementArray": [],
      "ObjectElementUnit": "2"
    },
    {
      "ObjectElementName": "Test ABC 2",
      "ObjectElementArray": [],
      "ObjectElementUnit": "5"
    }
  ],
  "Language": "en-US"
}

Output needed in this format, so CSV conversion can be executed

in2csv -f json --key Objects > output.csv

Output CSV required

ObjectElementName,ObjectElementUnit
Test ABC 1,2
Test ABC 2,5

Solution

  • If you want CSV, you should probably use jq's @csv filter, which essentially guarantees valid CSV output. For example, using your input:

    jq -r '
      ["ObjectElementName","ObjectElementUnit"],
      (.Objects[]
       | select(.ObjectElementName | test("ABC"))
       | [.ObjectElementName,.ObjectElementUnit] )
      | @csv' input.json
    

    produces:

    "ObjectElementName","ObjectElementUnit"
    "Test ABC 1","2"
    "Test ABC 2","5"
    

    However, if you're willing to take the risks, you could replace @csv by join(","), which in the present case would result in:

    ObjectElementName,ObjectElementUnit
    Test ABC 1,2
    Test ABC 2,5