user2977579
user2977579

Reputation: 13

Replacing specific fields in JSON from text file

I have a json structure and would like to replace strings in 2 fields that are in a seperate text file.

Here is the json file with 2 records:

{
  "events" : {
    "-KKQQIUR7FAVxBOPOFhr" : {
      "dateAdded" : 1487592568926,
      "owner" : "62e6aaa0-a50c-4448-a381-f02efde2316d",
      "type" : "boycott"
    },
    "-KKjjM-pAXvTuEjDjoj_" : {
      "dateAdded" : 1487933370561,
      "owner" : "62e6aaa0-a50c-4448-a381-f02efde2316d",
      "type" : "boycott"
    }
  },
  "geo" : {
    "-KKQQIUR7FAVxBOPOFhr" : {
      ".priority" : "qw3yttz1k9",
      "g" : "qw3yttz1k9",
      "l" : [ 40.762632, -73.973837 ]
    },
    "-KKjjM-pAXvTuEjDjoj_" : {
      ".priority" : "qw3yttx6bv",
      "g" : "qw3yttx6bv",
      "l" : [ 41.889019, -87.626291 ]
    }
  },
  "log" : "null",
  "users" : {
    "62e6aaa0-a50c-4448-a381-f02efde2316d" : {
      "events" : {
        "-KKQQIUR7FAVxBOPOFhr" : {
          "type" : "boycott"
        },
        "-KKjjM-pAXvTuEjDjoj_" : {
          "type" : "boycott"
        }
      }
    }
  }
}

And here is the txt file that I want to substitue in:

49.287130, -123.124026
36.129770, -115.172811

There are lots more records but I kept this to 2 for brevity.

Any help would be appreciated. Thank you.

Upvotes: 1

Views: 159

Answers (1)

peak
peak

Reputation: 116670

The problem description seems to assume that the ordering of the key-value pairs within a JSON object is fixed. Different JSON-oriented tools (and indeed different versions of jq) have different takes on this. In any case, the following assumes a version of jq that respects the ordering (e.g. jq 1.5); it also assumes that inputs is available, though that is inessential.

The key to the following solution is the helper function, map_nth_value/2, which modifies the value of the nth key in a JSON object:

def map_nth_value(n; filter):
  to_entries
  | (.[n] |= {"key": .key, "value": (.value | filter)} )
  | from_entries ;

[inputs | select(length > 0) | split(",") | map(tonumber)] as $lists
| reduce range(0; $lists|length) as $i
    ( $object;
      .geo |= map_nth_value($i; .l = $lists[$i] ) )

With the above jq program in a file (say program.jq), and with the text file in a file (say input.txt) and the JSON object in a file (say object.json), the following invocation:

jq -R -n --argfile object object.json -f program.jq input.txt

produces:

{
  "events": {
    "-KKQQIUR7FAVxBOPOFhr": {
      "dateAdded": 1487592568926,
      "owner": "62e6aaa0-a50c-4448-a381-f02efde2316d",
      "type": "boycott"
    },
    "-KKjjM-pAXvTuEjDjoj_": {
      "dateAdded": 1487933370561,
      "owner": "62e6aaa0-a50c-4448-a381-f02efde2316d",
      "type": "boycott"
    }
  },
  "geo": {
    "-KKQQIUR7FAVxBOPOFhr": {
      ".priority": "qw3yttz1k9",
      "g": "qw3yttz1k9",
      "l": [
        49.28713,
        -123.124026
      ]
    },
    "-KKjjM-pAXvTuEjDjoj_": {
      ".priority": "qw3yttx6bv",
      "g": "qw3yttx6bv",
      "l": [
        36.12977,
        -115.172811
      ]
    }
  },
  "log": "null",
  "users": {
    "62e6aaa0-a50c-4448-a381-f02efde2316d": {
      "events": {
        "-KKQQIUR7FAVxBOPOFhr": {
          "type": "boycott"
        },
        "-KKjjM-pAXvTuEjDjoj_": {
          "type": "boycott"
        }
      }
    }
  }
}

Upvotes: 1

Related Questions