From f03bf4cb703900963648e6b181e32a2223c16860 Mon Sep 17 00:00:00 2001 From: jbranchaud Date: Tue, 28 Nov 2023 16:16:50 -0600 Subject: [PATCH] Add Zip Two JSON Files Together Based On Shared ID as a jq TIL --- README.md | 3 +- ...-json-files-together-based-on-shared-id.md | 52 +++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 jq/zip-two-json-files-together-based-on-shared-id.md diff --git a/README.md b/README.md index 25e8594..1d4e256 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ pairing with smart people at Hashrocket. For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186). -_1351 TILs and counting..._ +_1352 TILs and counting..._ --- @@ -505,6 +505,7 @@ _1351 TILs and counting..._ - [Get The First Item For Every Top-Level Key](jq/get-the-first-item-for-every-top-level-key.md) - [Reduce Object To Just Entries Of A Specific Type](jq/reduce-object-to-just-entries-of-a-specific-type.md) - [Turn A List From A Command Into JSON](jq/turn-a-list-from-a-command-into-json.md) +- [Zip Two JSON Files Together Based On Shared ID](jq/zip-two-json-files-together-based-on-shared-id.md) ### Kitty diff --git a/jq/zip-two-json-files-together-based-on-shared-id.md b/jq/zip-two-json-files-together-based-on-shared-id.md new file mode 100644 index 0000000..e6a465b --- /dev/null +++ b/jq/zip-two-json-files-together-based-on-shared-id.md @@ -0,0 +1,52 @@ +# Zip Two JSON Files Together Based On Shared ID + +Let's say we have JSON file (`list1.json`) that contains an array of objects. +Maybe they represent metadata about some books. Something like this: + +```json +[ + { 'slug': 'the-subtle-knife', 'title': 'The Subtle Knife', ... }, + { 'slug': 'all-systems-red', 'title': 'All Systems Red', ... }, + { 'slug': 'piranesi-abc123', 'title': 'Piranesi', ... }, + ... +] +``` + +And then we have another JSON file (`list2.json`) in a similar format that +contains an additional piece of metadata tied to each slug: + +```json +[ + { 'slug': 'the-subtle-knife', 'author': 'Philip Pullman' }, + { 'slug': 'all-systems-red', 'author': 'Martha Wells' }, + { 'slug': 'piranesi-abc123', 'author': 'Susanna Clarke' }, + ... +] +``` + +And we want to pull the details from the second file and combine them into the +first file based on that shared identifier, in this case, the `slug`. + +Instead of copying over a ton of values manually or writing a full-fledged +script to do this, we can use a `jq` one-liner with the `--slurpfile` flag. + +``` +jq --slurpfile list1 list1.json --slurpfile list2 list2.json -n ' + $list1[] as $item1 + | $list2[] as $item2 + | select($item1.slug == $item2.slug) + | $item1 + $item2 +' + +[ + { 'slug': 'the-subtle-knife', 'title': 'The Subtle Knife', 'author': 'Philip Pullman', ... }, + { 'slug': 'all-systems-red', 'title': 'All Systems Red', 'author': 'Martha Wells', ... }, + { 'slug': 'piranesi-abc123', 'title': 'Piranesi', 'author': 'Susanna Clarke', ... }, + ... +] +``` + +This reads in both files as lists into named variables, selects for the items +that have matching `slug` values, and then unions those objects together. The +result will go to standard out, but it could also be redirected into a new JSON +file.