luckman212
luckman212

Reputation: 801

Merging filter-generated output with static JSON object using jq

I'm trying to use jq to iterate over some delimited text files, and generate objects from the rows.

I also want to add some "static" objects (json shell variable in the example below) to the generated results.

I've come up with the below solution, which does produce the output I want. But, because I'm not very confident in jq, every time I solve a problem with it, it feels like a monkey banging on a typewriter rather than a carefully crafted answer. So, I'm imaginging this could be incorrect.

data.txt

apple|fruit
Tesla|car
sparrow|bird

Test (bash shell):

$ json='[
  { "object": "love", "type": "emotion" },
  { "object": "Ukraine", "type": "country" }
]'

$ jq --slurp --raw-input --argjson extra "$json" '
split("\n") |
map(select(length>0)) |
map(split("|") | {
  object: .[0],
  type: .[1]
}) as $data |
$data + $extra' data.txt

Output:

[
  {
    "object": "apple",
    "type": "fruit"
  },
  {
    "object": "Tesla",
    "type": "car"
  },
  {
    "object": "sparrow",
    "type": "bird"
  },
  {
    "object": "love",
    "type": "emotion"
  },
  {
    "object": "Ukraine",
    "type": "country"
  }
]

Is this efficient?

Upvotes: 0

Views: 127

Answers (3)

Logan Lee
Logan Lee

Reputation: 997

[inputs / "|" | {object: .[0], type: .[1]}]

Demo

https://jqplay.org/s/XkDdy9-lBq

Or

reduce (inputs / "|") as [$obj, $typ] ([]; .+[{$obj, $typ}])

Demo

https://jqplay.org/s/5N3M-pfJIR

Upvotes: 0

Philippe
Philippe

Reputation: 26707

You can try this :

jq -nR --argjson extra "$json" '
    [inputs / "|" | {object:.[0], type:.[1]}] + $extra' data.txt

Upvotes: 1

pmf
pmf

Reputation: 36251

I don't know if it's more efficient but you could shorten the code using --raw-input or -R without --slurp or -s to linewise read in a stream of raw text (no need to split by newlines), the / operator to do the "column" splitting within a line, and reduce to successively build up your final structure, starting with your "static" data.

jq -Rn --argjson extra "$json" '
  reduce (inputs / "|") as [$object, $type] ($extra; . + [{$object, $type}])
' data.txt

If you want the "static" data at the end, add it afterwards and start with an empty array:

jq -Rn --argjson extra "$json" '
  reduce (inputs / "|") as [$object, $type] ([]; . + [{$object, $type}]) + $extra
' data.txt

Upvotes: 1

Related Questions