Indenting data bag JSON and Improving diffs
During the creation of our team's encrypted data bags for Chef, the JSON was generated on a single line in the files. Â While this is great for keeping the size small during deployments, it's not the most helpful when looking at a diff on github to see what was changed.
We found while we were re-encoding the data bags recently that the JSON was being split out into a more "prettified" format by a newer version of Knife. Â I put together a line of code (mixed bash and Python) to navigate through a folder tree and re-format the other JSON files in the same way as the new version of Knife (with a 2 space indention instead of the Python JSON library's standard 4):
find . -type f -iname "*.json" -print0 | while IFS= read -r -d $'\0' line; do if [ $(cat "$line" | wc -l) -eq 0 ] ; then JSONBLOB=$(cat "$line" | python -c "import json, sys; print(json.dumps(json.loads(sys.stdin.read()), indent=2, separators=(',', ': ')))"); echo "$JSONBLOB" > "$line"; fi; done
Here is the code spaced out into a slightly more readable format:
find . -type f -iname "*.json" -print0 | while IFS= read -r -d $'\0' line do if [ $(cat "$line" | wc -l) -eq 0 ] then JSONBLOB=$(cat "$line" | python -c "import json, sys; print(json.dumps(json.loads(sys.stdin.read()), indent=2, separators=(',', ': ')))") echo "$JSONBLOB" > "$line" fi done
Copying and pasting this command will run this in the current directory and all subdirectories. Â You can change the directory this is run on by changing the target in find command to find /directory/path.












