-1

I need to add or update values in multiple arrays without removing existed array values. Also I need to create objects If they did not exist.

somefile.json:

{ "messages": { "[email protected]": { "receivers": [ 1, 2, 3 ] }, "[email protected]": { "receivers": [ 7, 8, 9 ] } } } 

What I'm trying:

$ new='{"[email protected]":{"receivers":[1,2,3]},"[email protected]":{"receivers":[4,5,6]}}' $ jq --argjson data "$new" '.messages +=$data' somefile.json { "messages": { "[email protected]": { "receivers": [ 1, 2, 3 ] }, "[email protected]": { "receivers": [ 1, 2, 3 ] }, "[email protected]": { "receivers": [ 4, 5, 6 ] } } } 

Expected output:

{ "messages": { "[email protected]": { "receivers": [ 1, 2, 3 ] }, "[email protected]": { "receivers": [ 1, 2, 3, 7, 8, 9 ] }, "[email protected]": { "receivers": [ 4, 5, 6 ] } } } 

1 Answer 1

0

Sounds like a minor variations on your other question, which can be addressed the same with the Hash::Merge perl module (and I'm sure @Kusalananda will suggest the adaption of their jq answer shortly):

new='{"[email protected]":{"receivers":[1,2,3]},"[email protected]":{"receivers":[4,5,6]}}' NEW=$new perl -MList::Util=uniq -MJSON::PP -MHash::Merge -0777 -ne ' # jq-like pretty-printing: $j = JSON::PP->new->indent->indent_length(2)->space_after->canonical; # change the LEFT_PRECEDENT behaviour (the one used by default), # so that when merging an array with an array, the result is the # deduplicated list of the union of the elements, instead of just # the concatenation of the two lists: Hash::Merge::get_behavior_spec("LEFT_PRECEDENT") ->{ARRAY}->{ARRAY} = sub { [uniq @{$_[0]}, @{$_[1]}] }; $out = $j->decode($_); $out->{messages} = Hash::Merge::merge($out->{messages}, $j->decode($ENV{NEW})); print $j->encode($out)' somefile.json 

Which gives:

{ "messages": { "[email protected]": { "receivers": [ 1, 2, 3 ] }, "[email protected]": { "receivers": [ 4, 5, 6 ] }, "[email protected]": { "receivers": [ 7, 8, 9, 1, 2, 3 ] } } } 

The only change is that we're merging the $input->{messages} with the object in $new instead of merging the top-level objects.

1
  • Sorry, I find Perl syntax more like C++ which is too hard to read for me. Anyways thanks but I would really like to see a jq solution. Commented 14 hours ago

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.