5

With the following inputs:

# file1.json
{
  "uid": "1",
  "name": "jack"
}
{
  "uid": "2",
  "name": "jill"
}

# file2.json
{
  "fid": "a",
  "file": "sample1.txt",
  "uid": "1"
}
{
  "fid": "b",
  "file": "sample2.txt",
  "uid": "1"
}
{
  "fid": "c",
  "file": "sample3.txt",
  "uid": "2"
}

How do I go about inserting the name key-value pair to the object in the file2.json. The output I'm trying to get is as follows:

{
  "fid": "a",
  "file": "sample1.txt",
  "uid": "1",
  "name": "jack"
}
{
  "fid": "b",
  "file": "sample2.txt",
  "uid": "1",
  "name": "jack"
}
{
  "fid": "c",
  "file": "sample3.txt",
  "uid": "2",
  "name": "jill"
}

Solutions posted on merge json objects with jq and join two json files based on common key with jq utility or alternative way from command line both seems to only return the last matching pair. See below.

{"uid":"1","name":"jack","fid":"b","file":"sample2.txt"}
{"uid":"2","name":"jill","fid":"c","file":"sample3.txt"}
Dan Cruz
  • 63
  • 4

1 Answers1

6

You will need to "slurp" file1.json, e.g. by invoking jq as follows:

jq -n -f merge.jq --slurpfile file1 file1.json file2.json

where merge.jq contains:

INDEX($file1[]; .uid) as $dict
| inputs
| . + $dict[.uid]

def INDEX

If your jq does not have INDEX/2, then simply add its def:

def INDEX(stream; idx_expr):
  reduce stream as $row ({}; .[$row|idx_expr|tostring] = $row);
peak
  • 105,803
  • 17
  • 152
  • 177
  • Thanks for response, however, trying the above, I get the following error: jq: error: INDEX/2 is not defined at , line 1: INDEX($file1[]; .uid) as $dict jq: 1 compile error jq version is 1.5. – Dan Cruz Mar 03 '19 at 23:24
  • 1
    Now would be an excellent time to upgrade to the current version (1.6). Otherwise, please see the updated response above. – peak Mar 03 '19 at 23:41
  • Many thanks! Upgraded to 1.6 and it works perfectly. – Dan Cruz Mar 03 '19 at 23:52