Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace JSON Object Programmatically

I'm looking for the most effective way to replace a JSON Object in a file.

20150628 - Update at the bottom of this post

Here's the scenario:

I have a bunch of JSON files (many) and in these files are large chunks of JSON (sometimes 20-30K lines of it). These are configurations for various testing routines we have. Recently, a change was required to change an object from this:

"createdAt": {
    "year": 2014,
    "month": 11,
    "dayOfMonth": 24,
    "hourOfDay": 2,
    "minute": 22,
    "second": 54
}

to a format like this:

"createdAt":"2015-05-12T21:14:51Z"

Let's even make this easier. I want to replace all of the createdAt and updatedAt fields in my JSON object (which there can be many) with:

   "createdAt":"2015-05-12T21:14:51Z"

or

   "updatedAt":"2015-05-12T21:14:51Z"

There are NUMEROUS (100's of these) objects in each file, with different values for the fields. I need to go through and replace every createdAt and updatedAt object with the new format. The date's do not matter. I can have them be anything.

I can do this by hand, but it will literally take me a day or two to do of full time work (I know, I tried to do one file and after 1/2 hour I gave up, it was taking way too long).

How can I do this programmatically?

Regex? Sed? Something else?

Final note: I only need to do this once. After that, I won't need to do it again.

Thanks for any tips!

Example JSON: (Just imagine the real one is 30,000 lines!) :)

{ "products": [
          {
            "displayOrder": 3,
            "product": {
              "foo": "bar",
              "createdAt": {
                "year": 2014,
                "month": 11,
                "dayOfMonth": 24,
                "hourOfDay": 2,
                "minute": 22,
                "second": 54
              },
              "description": "Fizz Bin",
              "id": "8765309",
              "modelNumber": "call-it",
              "name": "Boom",
              "price": {
                "amount": 100,
                "currency": "USD"
              },
              "type": "Active",
              "updatedAt": {
                "year": 2015,
                "month": 1,
                "dayOfMonth": 27,
                "hourOfDay": 19,
                "minute": 33,
                "second": 25
              }
            }
          },
          {
            "displayOrder": 4,
            "product": {
              "foo": "barx",
              "createdAt": {
                "year": 2013,
                "month": 1,
                "dayOfMonth": 4,
                "hourOfDay": 3,
                "minute": 2,
                "second": 5
              },
              "description": "Fizzy Stuff",
              "id": "876511111",
              "modelNumber": "zoom-zoom-1000",
              "name": "Zoom Zoom 1000",
              "price": {
                "amount": 1000,
                "currency": "USD"
              },
              "type": "Active",
              "updatedAt": {
                "year": 2011,
                "month": 5,
                "dayOfMonth": 25,
                "hourOfDay": 15,
                "minute": 35,
                "second": 55
              }
            }
          }
        ]
}

UPDATE 20150628

For those wondering, here's the gulpfile I wrote to accomplish exactly what I wanted. It is based off of the accepted answer. It will recursively search the tree for what I'm looking for an replace it when found. Its not the prettiest thing in the world, but it did exactly what I needed and saved me a couple weeks of manual time. Total time to process all my files? Under 100ms. Amazing.

var gulp = require('gulp');
var change = require('gulp-change');

function searchTreeForDates(obj) {
    if(typeof(obj) === 'object') {
        for (var key in obj) {
            if (typeof(obj[key]) === 'object' && (key === 'createdAt' || key === 'updatedAt')) {
                obj[key] = "2015-06-29T00:53:00Z";
            } else {
                obj[key] = searchTreeForDates(obj[key])
            }
        }
    }
    return obj; 
}

function updateDate(content) {
    var obj = JSON.parse(content);
    obj = searchTreeForDates(obj);
    return JSON.stringify(obj);
}

gulp.task('change', function() {
    return gulp.src('*.json')
        .pipe(change(updateDate))
        .pipe(gulp.dest('changed/'))
});
like image 716
Donn Felker Avatar asked Oct 31 '22 03:10

Donn Felker


1 Answers

Here is an initial stab. You implement your own "date parsing logic." It requires you to install gulp. And save this in a gulpfile.js . You would need to possibly loop over all the properties that are "date" objects. But that logic isn't that hard.

var gulp = require('gulp');
var change = require('change');

function translateDate(dateField){
    return dateField.A + dateField.b + ...;

}
function updateDate(content) {
    var obj = JSON.parse(content);
    //loop over the obj properties and call the below
    // for the ones you want to change.
    obj.dateField = translateDate(obj.dateField);
    return JSON.stringify(obj);
}

gulp.task('change', function() {
    return gulp.src('**/*.json')
      .pipe(change(updateDate))
      .pipe(gulp.dest('changed/'))
});
like image 118
Nix Avatar answered Nov 02 '22 23:11

Nix