0

I a have a short TSV stream that outputs key/value pairs and I would like to create a JSON object out of it, with jq.

For now I have this code, which generates a stack of JSON objects:

printf '%s\t%s\n' key1 val1 key2 val2 |

jq -R 'rtrimstr("\n") | split("\t") | { (.[0]): .[1] }'
{
  "key1": "val1"
}
{
  "key2": "val2"
}

I can pipe it to jq -s 'add' for getting my expected output:

{
  "key1": "val1",
  "key2": "val2"
}

But, is it possible to get this output with a single jq call?

peak
  • 105,803
  • 17
  • 152
  • 177
Fravadona
  • 13,917
  • 1
  • 23
  • 35

1 Answers1

1

Use -n and inputs to access the stream item by item.

For instance using reduce:

jq -Rn 'reduce (inputs/"\t") as [$k,$v] ({}; .[$k] = $v)'

Or using from_entries:

jq -Rn '[inputs/"\t" | {key: .[0], value: .[1]}] | from_entries'
pmf
  • 24,478
  • 2
  • 22
  • 31
  • Thank you, I was missing the `-n` in my tests with `inputs` and `reduce` – Fravadona Jul 28 '22 at 00:09
  • 1
    @Fravadona Sometimes the `-n` is not indispensable. In such cases you can use `.` in the initial context of `reduce`, and process just the subsequent items using `input(s)`. Example: `printf '%s\n' val1 val2 val3 | jq -R 'reduce inputs as $i (.; . += ",\($i)")'` yields `"val1,val2,val3"`. – pmf Jul 28 '22 at 00:12