Jason (jcreed) wrote,
Jason
jcreed

Have I mentioned lately how much I love jq? I love it so much. I've seen it billed as "sed for json", but as a PL nerd it really goes a couple steps beyond that.

One obvious thing is that it lets you program in the list monad with very simple syntax. I can do things like
$ echo "[[1,2,3],[4,5,6],[7,8,9]]" | jq ".[][]"
1
2
3
4
5
6
7
8
9

and
$ echo '[{"foo":[4,5],"bar":9},{"foo":[6,7,8]}]' | jq "[.[].foo[]]"
[
  4,
  5,
  6,
  7,
  8
]


But that's no big deal, you say, you're used to list comprehensions from python and ruby and whatever. But can you automatically capture the provenance of data loci used at some point during nested list comprehensions and apply functions to them in-place in a complex, heterogeneous data-structure?
$  echo '[{"foo":[4,5],"bar":9},{"foo":[6,7,8]}]' | jq ".[].foo[] |= (. + 100)"
[
  {
    "foo": [
      104,
      105
    ],
    "bar": 9
  },
  {
    "foo": [
      106,
      107,
      108
    ]
  }
]

Like, actually, if you can do that in any reasonable way in python or ruby or whatever, I would be interested to know. But this sort of feature is novel to me, at least - jq's the first place I've encountered it. You can even do arbitrarily nested searches like
$ echo '[{"foo":[4,5],"bar":9},{"foo":[[[[{"baz":"here is what I am looking for"}]]],7,8]}]' | \
  jq '(..|select(type=="object" and has("baz"))|.baz) |= (. + " and now I have changed it")'
[
  {
    "foo": [
      4,
      5
    ],
    "bar": 9
  },
  {
    "foo": [
      [
        [
          [
            {
              "baz": "here is what I am looking for and now I have changed it"
            }
          ]
        ]
      ],
      7,
      8
    ]
  }
]
Tags: javascript, jq
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 6 comments