jq: iterate over every element of list and replace it with value

Viewed 779

I've got this json-file:

{
  "name": "market",
  "type": "grocery",
  "shelves": {
    "upper_one": [
      "23423565",
      "23552352",
      "08789089"
    ]
  }
}

I need to iterate over every element of an list (upper_one), and replace it with other value.


I've tried this code:

#/bin/bash

for product in $(cat first-shop.json| jq -r '.shelves.upper_one[]')
do
  cat first-shop.json| jq --arg id "$((1 + $RANDOM % 10))" --arg product "$product" -r '.shelves.upper_one[]|select(. == $product)|= $id' 
done

But I got this kind of output:

1
23552352
08789089
23423565
10
08789089
23423565
23552352
7

Is it possible to iterate over list with jq, replace values with value from another function (like $id in the code), and print the whole final json with substituted values?


I need this kind of output:

{
  "name": "market",
  "type": "grocery",
  "shelves": {
    "upper_one": [
      "1",
      "10",
      "7"
    ]
  }
}

not just elements of "upper_one" list thrice.

2 Answers

You could try the following script :

#!/usr/bin/env bash

for product in $(jq -r '.shelves.upper_one[]' input.json)
do
    id="$((1 + $RANDOM % 10))"
    newIds+=("$id")
done

jq  '.shelves.upper_one = $ARGS.positional' input.json --args "${newIds[@]}"

IMHO its better to use some scripting language and manipulate objects programmatically. If bash and jq is your only option - this do the job though not nice

$ jq '.shelves.upper_one[] |= (sub("23423565";"1") | sub("23552352";"10") | sub("08789089";"7"))' your.json
{
  "name": "market",
  "type": "grocery",
  "shelves": {
    "upper_one": [
      "1",
      "10",
      "7"
    ]
  }
}

consider conversion to numbers with | tonumber

Related