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.







