Reputation: 59
I'm building a bash script that will read the response from an API and insert a value within a [] list (not {} array) if the value isn't present. Fake example response from API:
#response.json contains:
{
"foods": {
"menu": [
"tacos",
"spaghetti",
"pizza",
"chicken_florentine",
"bacon_cheeseburge",
"chow_mein",
"sushi",
"chocolate",
"whiskey"
]
}
}
The variable from my bash script is order="lasagna"
. If 'foods.menu[]'
contains $order
then do nothing, else insert $order
value into 'foods.menu[]'
.
Using bash variable order="lasagna"
which currently doesn't exist in 'foods.menu[]'
, the resulting json should be:
{
"foods": {
"menu": [
"tacos",
"spaghetti",
"pizza",
"chicken_florentine",
"bacon_cheeseburge",
"chow_mein",
"sushi",
"chocolate",
"whiskey",
"lasagna" <----
]
}
}
I started with trying a bash for
loop and variations of jq's if-then-else
, select
, and contains
but went down a rabbit hole. Any help is appreciated.
Upvotes: 3
Views: 115
Reputation: 36078
Here's another way using the alternative operator //
to default to the array's length
for the item's index:
jq --arg order 'lasagna' '
(.foods.menu | .[index($order) // length]) = $order
' response.json
Adding a list of items in the same manner:
jq '.foods.menu |= reduce $ARGS.positional[] as $order (.;
.[index($order) // length] = $order
)' response.json --args 'lasagna' 'sushi' 'milk'
Upvotes: 1
Reputation: 50750
You don't need a loop for that
jq --arg order lasagna '.foods.menu |= if index($order) then . else . + [$order] end' response.json
But you may need one for inserting multiple orders
jq 'reduce $ARGS.positional[] as $order (.;
.foods.menu |= if index($order) then . else . + [$order] end
)' response.json --args apple banana sushi
Upvotes: 6
Reputation: 246807
I don't know if this fits with any unspoken requirements.
Add the item regardless, and then unique
the results:
echo "$result" | jq --arg order pizza '.foods.menu |= (. + [$order] | unique)'
{
"foods": {
"menu": [
"bacon_cheeseburge",
"chicken_florentine",
"chocolate",
"chow_mein",
"pizza",
"spaghetti",
"sushi",
"tacos",
"whiskey"
]
}
}
The resulting array is sorted. If there were any duplicates in the input, those are gone.
Upvotes: 3