buddhabath
buddhabath

Reputation: 674

JQ: Replace keys with corresponding value in another file

I'm trying to replace the value of a key in my original JSON with the value of an object with the corresponding key in another document.

These are my two files: File 1:

{
    "-KaM0otlgWxXniYiacFe": {
        "-LNxx1IiX6oYTxJ4IXx2": true
    },
    "-KlJTvbfonIMI_-YfS5R": {
        "-LNxx1IbaB-yrZ623hrX": true
    }
}

File 2:

{
    "-KaM0otlgWxXniYiacFe": {
        "a": "-L-b__nH9PlMcz0stDDE",
        "b": "-L7ZNKSZy570TlrQUzHM",
        "c": "-Kaae3MsQUyViCKPs8Iv"
    },
    "-KlJTvbfonIMI_-YfS5R": {
        "a": "-LAlXKfUUTdYDeCZH-u-",
        "b": "-L7ZNKSTnob7w0HXjHr6",
    "    c": "-KYYicPD7VA9DEF_rus3"
    }
}

The goal is to create 3 new files, where the original keys have been replaced with the value of a, b and c in each file.

Desired result when looking against "a":

{
    "-L-b__nH9PlMcz0stDDE": {
        "-LNxx1IiX6oYTxJ4IXx2": true
    },
    "-LAlXKfUUTdYDeCZH-u-": {
        "-LNxx1IbaB-yrZ623hrX": true
    }
}

I have tried using something along the lines of:

cat file1.json | jq --slurpfile file2 file2.json '| map(with_entries(.key = .file2[.key].a'

But I'm feeling rather clueless as I havn't used jq before.

Any help is appreciated.

Update:

How do I handle the scenario where the key from File 1 might not exist in File 2, resulting in the "Cannot use null (null) as object key"?

Upvotes: 3

Views: 1927

Answers (3)

peak
peak

Reputation: 116977

If you have more than a trivial number of keys "a", "b", ..., and if you don't mind if the output files are minified, you could avoid the multiple calls to jq using the approach illustrated here:

< file1.json jq -rc --argjson keys '["a", "b", "c"]' --argfile file2 <(file2) '
  $keys[] as $k 
  | ($k, (with_entries(.key |= $file2[.][$k]) ))
' | awk 'file {print > file ".json"; file=0; next} {file=$0}'

You could go one step further and compute $keys programatically using (for example):

   [$file2[]][0]|keys_unsorted

Upvotes: 2

peak
peak

Reputation: 116977

How do I handle the scenario where the key from File 1 might not exist in File 2, resulting in the "Cannot use null (null) as object key"?

The most obvious thing to do would probably be to test whether the object has the key:

with_entries(.key |= (if $file2[.]|has($k) then $file2[.][$k]  else . end))

Upvotes: 2

oguz ismail
oguz ismail

Reputation: 50805

Not an expert on jq, but here is what I've come up with:

jq --arg k a --argfile file2 file2.json 'with_entries(.key |= $file2[.][$k])' file1.json > out_a.json

Change --arg k a and out_a.json for other keys and output files.

Upvotes: 2

Related Questions