0

I am writing a json file to a key value properties file:

Json Example:

{
   "id":"0",
   "meta":"down",
   "type":"1",
   "direction":"0",
   "interval":"1800"
}

and need to write the file like below(need to match the indentation):

id               = 0      
meta             = down   
type             = 1      
direction        = 0      
interval         = 1800   

Now, after dumping the json, I am replacing texts, which works fine. But I am not able to get the proper indentation. Below is my code and output:

def updateConfigFile(filename):

    with open(filename, 'U') as f:

       newText=f.read()
       while ':' in newText:
          newText=newText.replace(':', '        = ')

   while ',' in newText:
      newText=newText.replace(',', '   ')          

with open(filename, "w") as f:
   f.write(newText)   

Output:

direction        =  0    
  stallTimeout        =  60    
  description        =  down    
  rampTime        =  4    
  deepDepth        =  14    
  deepWindow        =  5   
  id  = 1

How can I achieve proper indentation? Thanks

Pinaki Mukherjee
  • 1,326
  • 2
  • 17
  • 29

1 Answers1

1

You should process JSON as JSON, not as raw text. In particular, you should not rely on some special formatting of the JSON file.

Henceforth, I assume that this is the content of your json file:

{"id":"0", "meta": "down", "type": "1", "direction": "0", "interval":"1800"}

saved under exampleJson.json.

You can convert your json to the properly formatted string as follows:

import json

def configFileToString(filename):
  with open(filename, 'r') as f:
    j = json.load(f)
    return "\n".join(["%-20s= %s" % (k, j[k]) for k in j])  

print(configFileToString("exampleJson.json"))

It produces the following string:

id                  = 0
meta                = down
type                = 1
direction           = 0
interval            = 1800

The crucial part is the "%-20s= %s"-format string. The %-20s means: pad to width 20, left aligned.

Saving this string to file should not be a problem, I hope.

Andrey Tyukin
  • 38,712
  • 4
  • 38
  • 75
  • 1
    `print(f'{k.ljust(19)} = {v}', file=output_handle)` works too if you're using Python 3.6. – Blender Mar 31 '18 at 03:30
  • @Blender Thanks for the hint! (Or rather, two hints: `f'...'` and `str.ljust`) Is the `f'...'`-syntax considered so *vastly* more pythonic since 3.6 that I should update the answer, or can I leave it as-is so that the solution works with older python versions? ;) I actually suspect that because `.ljust` is a separate method call, the "closer-to-C-sprintf"-version could actually be tiny bit faster, shouldn't it? – Andrey Tyukin Mar 31 '18 at 03:39
  • @AndreyTyukin: `f`-strings are (surprisingly) ~18x faster than `%`-formatting and ~30x faster than new-style string formatting in this case, but I was suggesting it only because I can never remember the `%`-formatting syntax. – Blender Mar 31 '18 at 06:11