From 7b380d146eccc9bcb03f8aa2df3f5b7f0a32a8f2 Mon Sep 17 00:00:00 2001 From: Michele Cereda Date: Thu, 20 Jun 2024 23:55:15 +0200 Subject: [PATCH] chore(kb/jq): improve readibility --- knowledge base/jq.md | 64 +++++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 22 deletions(-) diff --git a/knowledge base/jq.md b/knowledge base/jq.md index 1387212..a330f1f 100644 --- a/knowledge base/jq.md +++ b/knowledge base/jq.md @@ -6,9 +6,22 @@ ## TL;DR +
+ Installation + +```sh +brew install 'jq' +docker pull 'ghcr.io/jqlang/jq' +``` + +
+
+ Usage + ```sh # Only list keys. jq 'keys' 'file.json' +docker run --rm -i 'ghcr.io/jqlang/jq' 'keys' 'file.json' # Sort all the keys. jq --sort-keys '.' 'input.json' > 'output.json' @@ -20,11 +33,13 @@ jq '.spec.template.spec.containers[]?.env?' 'manifest.kube.json' # Add elements to lists. jq '.orchestrators += [{"orchestratorVersion": "1.24.9"}]' -jq --arg REGION ${AWS_REGION} '.spec.template.spec.containers[]?.env? += [{name: "AWS_REGION", value: $REGION}]' '/tmp/service.kube.json' +jq --arg 'REGION' "${AWS_REGION}" \ + '.spec.template.spec.containers[]?.env? += [{name: "AWS_REGION", value: $REGION}]' \ + '/tmp/service.kube.json' yq -iy '.resources+=["awx.yaml"]' 'kustomization.yaml' # Delete keys from objects. -jq 'del(.items[].spec.clusterIP)' /tmp/service.kube.json +jq 'del(.items[].spec.clusterIP)' '/tmp/service.kube.json' jq 'del(.country, .number, .language)' … # Remember ranges are **exclusive** of the end index. jq 'del(.[0,1,2])' … @@ -39,12 +54,14 @@ jq -r 'to_entries[] | "\(.key) \"\(.value)\""' 'file.json' # Change single values. # A.K.A. update values. -jq '.extensionsGallery - | .serviceUrl |= "https://marketplace.visualstudio.com/_apis/public/gallery"' \ - /usr/lib/code/product.json -jq --arg NAMESPACE ${NAMESPACE} \ - '.spec.template.spec.containers[]?.env[]? |= {name: .name, value: (if .name == "KUBERNETES_NAMESPACE" then $NAMESPACE else .value end)}' \ - /tmp/service.kube.json +jq '.extensionsGallery | .serviceUrl |= "https://marketplace.visualstudio.com/_apis/public/gallery"' \ + '/usr/lib/code/product.json' +jq --arg 'NAMESPACE' "$NAMESPACE" \ + '.spec.template.spec.containers[]?.env[]? |= { + "name": .name, + "value": (if .name == "KUBERNETES_NAMESPACE" then $NAMESPACE else .value end) + }' \ + '/tmp/service.kube.json' # Change multiple values at once. jq '.extensionsGallery @@ -62,26 +79,27 @@ jq '.extensionsGallery + { jq '.[0] * .[1]' '1.json' '2.json' # Only show ('select') elements which specific attribute's value is in a list. -jq '.[]|select(.PrivateIpAddress|IN("172.31.6.209","172.31.6.229"))|.PrivateDnsName' +jq '.[]|select(.PrivateIpAddress|IN("172.31.6.209","172.31.6.229"))|.PrivateDnsName' '-' # Add elements from arrays with the same name from other files. -jq '.rules=([input.rules]|flatten)' starting-rule-set.json ending-rule-set.json -jq '.rules=([inputs.rules]|flatten)' starting-rule-set.json parts/*.json +jq '.rules=([input.rules]|flatten)' 'starting-rule-set.json' 'ending-rule-set.json' +jq '.rules=([inputs.rules]|flatten)' 'starting-rule-set.json' 'parts'/*'.json' # Put specific keys on top. -jq '.objects = [(.objects[] as $in | {type,name,id} + $in)]' prod/dataPipeline_deviceLocationConversion_prod.json +jq '.objects = [(.objects[] as $in | {type,name,id} + $in)]' 'prod/dataPipeline_deviceLocationConversion_prod.json' # Convert Enpass' JSON export to a YAML file -jq '.items[] | {title, fields} | .title + ":", (.fields[] | select(.value != "") | " " + .label + ": " + .value)' test.json -cr +jq '.items[] | {title, fields} | .title + ":", (.fields[] | select(.value != "") | " " + .label + ": " + .value)' \ + 'test.json' -cr # Refactor an AWS DataPipeline definition. -jq --sort-keys '.' datapipeline.json > /tmp/sorted.json \ +jq --sort-keys '.' datapipeline.json > '/tmp/sorted.json' \ && jq '.objects = [(.objects[] as $in | {type,name,id} + $in | with_entries(select(.value != null)))]' \ - /tmp/sorted.json > /tmp/reordered.json \ -&& mv /tmp/reordered.json datapipeline.json + '/tmp/sorted.json' > '/tmp/reordered.json' \ +&& mv '/tmp/reordered.json' 'datapipeline.json' # Extract the value of elements with specific keys. -kubectl get pods -o yaml \ +kubectl get pods -o 'yaml' \ | yq -y ' .items[] | select(.metadata.name | test("^runner-.*")) @@ -91,21 +109,23 @@ kubectl get pods -o yaml \ # Recursively find all the properties whose key is 'errors' whether it exists or not. # '..' unrolls the object, '?' checks for the value or returns null, and 'select(.)' is like a filter on truthy values. -jq '[.. | .errors?[0] | select(.) ]' /tmp/helm.template.out.json +jq '[.. | .errors?[0] | select(.) ]' '/tmp/helm.template.out.json' # Find all images in a helm chart explicitly or implicitly using the tag 'latest'. -helm template chartName \ +helm template 'chartName' \ | yq -r ' .. | .image? | select(.) | select(.|test(".*:.*")|not), select(.|test(".*:$")), select(.|test(".*:latest"))' \ - - + '-' # Check that the 'backend.url key' in a 'Pulumi.yaml' file is not 'file://' and fail otherwise. yq -e '(.backend.url|test("^file://")?)|not' 'Pulumi.yaml' ``` +
+ ## Further readings - [JQ recipes] @@ -123,10 +143,10 @@ yq -e '(.backend.url|test("^file://")?)|not' 'Pulumi.yaml' - [jq: select where .attribute in list] - [change multiple values at once]: https://stackoverflow.com/questions/47355901/jq-change-multiple-values#47357956 [deleting multiple keys at once with jq]: https://stackoverflow.com/questions/36227245/deleting-multiple-keys-at-once-with-jq