Search code examples
pythonpython-3.xcson

Find a string in a file and replace the next lines


I have a CSON (Coffeescript JSON) file that looks something like this:

'main key':

    subkey: 
        someKey: 'some value'
        someKey: 'some value'

    subkey:
        someKey: 'some value'
        someKey: 'some value'

    specialKey: [
        'special value X'
        'special value Y'
    ]

    subkey:
        someKey: 'some value'
        someKey: 'some value'
        someKey: 'some value'

#And the list goes on and on...

So I want to find and target specialKey and replace both special value X and special value Y to other values, keeping in mind that by the nature of CSON it is indentation sensitive.

I've thought about getting the line number from specialKey and replacing the next two line numbers but for the life of me I haven't been able to find a way to edit a specific line by number in Python.

(As a side note, I DO know about the pycson library but I haven't been able to get it to output anything other than single line JSON, and I'd rather keep it in CSON as I want to keep readability in a long file and wouldn't want to mess with the user's original file.)


Solution

  • Okay, once again I've answered my own question. It may not be the most efficient or elegant but here it is:

    from shutil import move
    
    count = 0
    with open('fileInput.cson') as fileIn, open('fileInput.cson.tmp', 'w') as fileOut:
        for item in fileIn:
            if count == 1:
                item = "      \'NEW special value Y\'\n"
                count -= 1
            if count == 2:
                item = "      \'NEW special value X\'\n"
                count -= 1
    
            if item.strip().startswith('specialKey:'):
                count = 2
    
            fileOut.write(item)
    
    move('fileInput.cson.tmp', 'fileInput.cson')
    

    A few things to keep in mind:

    1. I was not able to edit the file line by number directly so instead it creates a secondary tmp file which is the result of the original file plus the changes it makes, and when it is done it replaces the original one, so file permissions are something to keep in mind.
    2. It loops through all the lines in the original file, thus if the file is too big it may affect the performance or time of execution.
    3. As mentioned in the question, spaces are very important in CSON as they are in Python, therefore it's crucial to check that the ones you are replacing them with match the original ones

    If you can think of any better solution/improvements to this one please let me know :) I'm all ears (or eyes perhaps)


    Credits: