Home > OS >  Use jq to filter content by a certain key, but no output
Use jq to filter content by a certain key, but no output

Time:10-20

I have similar question as how-to-use-jq-to-find-all-paths-to-a-certain-key and also checked the accepted answer.

The solution described in answer works for the exactly same input as the ticket, but after I updated the json a little bit as following (remove last foo part), I can't get any output by filter:

fromstream(tostream | select(.[0]|index("foo")))

The updated input json:

{
    "A": {
      "A1": {
        "foo": {
          "_": "_"
        }
      },
      "A2": {
        "_": "_"
      }
    },
    "B": {
      "B1": {}
    }
}

The expected output should be:

{
    "A": {
      "A1": {
        "foo": {
          "_": "_"
        }
      }
    }
}

But I got nothing. You can check here https://jqplay.org/s/s21FFUeoQz0.

I've also tried the filter without fromstream:

tostream | select(.[0]|index("foo"))

The output will be as following, it seems work here.

[["A","A1","foo","_"],"_"]
[["A","A1","foo","_"]]
[["A","A1","foo"]]

So I suspect the fromstream has some problem. Can anyone help me figure out? Thanks!

CodePudding user response:

fromstream(tostream | select(length==1 or (.[0]|index("foo"))))

Depending on your requirements, you might be able to make things more efficient by wrapping the above expression in a call to first().

—-

FYPI, a less obscure approach would be along the lines of:

paths as $p
| select($p[-1]=="foo")
| getpath($p) as $v
| {} | setpath($p;$v)

CodePudding user response:

You're looking for something like this:

. as $in
| reduce (paths | select(.[-1] == "foo")) as $p (
    null;
    setpath($p; $in | getpath($p))
)

Online demo

  • Related