Given json:
[
  {
    "path": "Module1/",
    "users": [
      "john",
      "jane"
    ]
  },
  {
    "path": "Module2/",
    "users": [
      "mike",
      "mary"
    ]
  },
  {
    "path": "Module3/",
    "users": [
      "billy",
      "bonny"
    ]
  }
]
Given array of files:
[
  "Module1/file.java",
  "Module3/file.java"
]
How can I get the users for which any of the files match the path?
Expected output:
[
  "john",
  "jane",
  "billy",
  "bonny"
]
I recently found this answer to a similar question, which cleverly builds regex filter and passes as arg in jq: https://stackoverflow.com/a/54630000/8784215
I set up similarly:
users='[{"path":"Module1/","users":["john","jane"]},{"path":"Module2/","users":["mike","mary"]},{"path":"Module3/","users":["billy","bonny"]}]'
files='["Module1/file.java","Module3/file.java"]'
filter=($(echo $files | jq -r  '. | join(" ")'))
echo $users | jq --arg re "$(IFS="|"; echo "${filter[*]}")" '[.[] | select(.path | test($re)) | .users[]]'
But the problem is that path is being matched against file, when it should be the other way around.
Any ideas?
You can use ìnside to flip arguments for a contains test which performs a substring matching. Use any to select on first match, and input to read the second input (array of files):
jq 'input as $f | map(select(any(.path | inside($f[]); .)).users[])' input.json files.json
[
  "john",
  "jane",
  "billy",
  "bonny"
]
Demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With