diff options
author | Ngô Ngọc Đức Huy <huyngo@disroot.org> | 2021-06-13 11:24:07 +0700 |
---|---|---|
committer | Ngô Ngọc Đức Huy <huyngo@disroot.org> | 2021-06-13 11:24:07 +0700 |
commit | f5f00b800f4158aeef28f73407e2064b29113ac3 (patch) | |
tree | 20564ecedecad661aea3411548dccfce7cba9626 | |
parent | 687e0787abcd9b019da285534764acdab5e262df (diff) | |
download | blog-f5f00b800f4158aeef28f73407e2064b29113ac3.tar.gz |
Update blog
-rw-r--r-- | content/posts/2021-06-13-jq.md | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/content/posts/2021-06-13-jq.md b/content/posts/2021-06-13-jq.md new file mode 100644 index 0000000..49d2148 --- /dev/null +++ b/content/posts/2021-06-13-jq.md @@ -0,0 +1,204 @@ +--- +title: "jq is a powerful JSON processor" +date: 2021-06-13 +categories: [ blog ] +tags: [unix, jq, json, cli, guide, tinker] +--- + +So lately I've been using `jq` quite a bit. It is a CLI JSON processor that +makes your life easier if you have to deal with a lot of JSON. Here I'm going +to give two examples of how it's used. + +# Search response + +I've been dealing with JSON from Elasticsearch API[^0], but as they would not +release their documents under a free license, I will take an example from +OpenSearch instead[^1]: + +```json +{ + "took": 39, + "timed_out": false, + "_shards": { + "total": 68, + "successful": 68, + "skipped": 0, + "failed": 0 + }, + "hits": { + "total": { + "value": 5837, + "relation": "eq" + }, + "max_score": 7.8623476, + "hits": [ + { + "_index": "new_shakespeare", + "_type": "_doc", + "_id": "100763", + "_score": 7.8623476, + "_source": { + "type": "line", + "line_id": 100764, + "play_name": "Troilus and Cressida", + "speech_number": 43, + "line_number": "3.1.68", + "speaker": "PANDARUS", + "text_entry": "Sweet queen, sweet queen! thats a sweet queen, i faith." + } + }, + { + "_index": "shakespeare", + "_type": "_doc", + "_id": "28559", + "_score": 5.8923807, + "_source": { + "type": "line", + "line_id": 28560, + "play_name": "Cymbeline", + "speech_number": 20, + "line_number": "1.1.81", + "speaker": "QUEEN", + "text_entry": "No, be assured you shall not find me, daughter," + } + } + ] + } +} +``` + +Woah that's long! + +How do you know how much time it took? I want to measure the performance. + +```sh +$ curl ... | jq '.took' +39 +``` + +Nice. Not very helpful, though---I can easily see that at the top of the +result. I want to see which responses were returned. + +```sh +$ curl ... | jq '.hits.hits' +[ + { + "_index": "new_shakespeare", + "_type": "_doc", + "_id": "100763", + "_score": 7.8623476, + "_source": { + "type": "line", + "line_id": 100764, + "play_name": "Troilus and Cressida", + "speech_number": 43, + "line_number": "3.1.68", + "speaker": "PANDARUS", + "text_entry": "Sweet queen, sweet queen! thats a sweet queen, i faith." + } + }, + { + "_index": "shakespeare", + "_type": "_doc", + "_id": "28559", + "_score": 5.8923807, + "_source": { + "type": "line", + "line_id": 28560, + "play_name": "Cymbeline", + "speech_number": 20, + "line_number": "1.1.81", + "speaker": "QUEEN", + "text_entry": "No, be assured you shall not find me, daughter," + } + } +] +``` + +The response is the value of `hits` inside a `hits`, so the query is +`.hits.hits`. How intuitive! + +But this is hard to read. Let's just take the `play_name` of the result. + +```sh +$ curl ... | jq .hits.hits[]._source.play_name +"Troilus and Cressida" +"Cymbeline" +``` + +Neat! But how does it work? The brackets `[]` signifies that we should take +all the results, from each of which the value for `._source.play_name` is +taken. + +There might be the option to write that in the search query DSL, which also +reduces the data transferred, but I bet this is much easier to write. + +# Wallpaper + +I use `feh` for setting wallpaper, which can take an image from the internet. +Previously, I used a static list that I collected myself, but I recently +discovered a wallpaper API from [wallhaven](https://wallhaven.cc/help/api). + +Let's say, I want to get a space image as wallpaper, I would use this command: + +```sh +curl -s 'https://wallhaven.cc/api/v1/search?q=space&ratios=16x9&sorting=toplist' +``` + +Where `q` is the query, `ratios` is the image ratio so that it fits the screen, +and `sorting` is the way the results would be sorted before pagination. The +results is long, but it looks like this: + +```json +{ + "data": [ + { + "id": "l3zmwy", + "url": "https://wallhaven.cc/w/l3zmwy", + "short_url": "https://whvn.cc/l3zmwy", + "views": 67050, + "favorites": 705, + "source": "https://www.artstation.com/artwork/YaQwgP", + "purity": "sfw", + "category": "general", + "dimension_x": 1920, + "dimension_y": 1080, + "resolution": "1920x1080", + "ratio": "1.78", + "file_size": 781731, + "file_type": "image/jpeg", + "created_at": "2021-05-18 19:26:23", + "colors": [ + "#424153", + "#000000", + "#663300", + "#996633", + "#999999" + ], + "path": "https://w.wallhaven.cc/full/l3/wallhaven-l3zmwy.jpg", + "thumbs": { + "large": "https://th.wallhaven.cc/lg/l3/l3zmwy.jpg", + "original": "https://th.wallhaven.cc/orig/l3/l3zmwy.jpg", + "small": "https://th.wallhaven.cc/small/l3/l3zmwy.jpg" + } + }, + ... + ] +} +``` + +So, to get the image path from this, I run: + +```sh +curl ... | jq -r .data[].path | shuf -n 1 | feh --bg-center +``` + +I use `shuf` because I'd like a new wallpaper every time I run this script. +Put this as the startup script or add a cron job and you'll have a changing +wallpaper. Disclaimer: this script does not always work, because of `feh`. +If you're using GNOME, for example, `feh` can't be used to set background. + +[^0]: Yes I know it's no longer free software (it still partially is I think). + I have no choice, and I would still be more at peace with a source available + software that is self-hostable. +[^1]: Copyright 2021 OpenSearch contributors. Released under Apache License. |