How can I pretty-print JSON in a shell script?
Is there a (Unix) shell script to format JSON in human-readable form?
Basically, I want it to transform the following:
{ "foo": "lorem", "bar": "ipsum" }
… into something like this:
{
"foo": "lorem",
"bar": "ipsum"
}
You can pretty-print JSON in a shell script using several methods, with jq being the most popular and powerful tool. The simplest approach is using cat file.json | jq . or jq . file.json to convert compact JSON into a human-readable format with proper indentation. Other alternatives include Python’s json.tool, json_pp, or PHP’s JSON pretty-printing capabilities.
Contents
- Getting Started with jq
- Alternative Methods Without External Tools
- Creating a Reusable Shell Script
- Advanced jq Features and Customization
- Handling Common JSON Formatting Issues
- Performance Considerations
Getting Started with jq
jq is the most widely used and powerful command-line JSON processor available for Unix systems. It’s designed specifically for working with JSON data in shell environments and offers excellent pretty-printing capabilities.
Installing jq
First, you’ll need to install jq on your system. The installation process varies depending on your Linux distribution:
For Debian/Ubuntu systems:
sudo apt-get install jq
For Red Hat/CentOS/Fedora systems:
sudo yum install jq
For macOS:
brew install jq
For other systems: You can download the binary from the official jq website or compile from source.
Basic Pretty Printing
Once installed, jq makes pretty-printing JSON incredibly simple:
# Basic pretty printing
cat file.json | jq .
# Or more concisely:
jq . file.json
This will transform compact JSON like:
{"foo":"lorem","bar":"ipsum"}
Into a properly formatted version:
{
"foo": "lorem",
"bar": "ipsum"
}
Customizing Indentation
You can control the indentation level using the --indent option:
# Use 4 spaces for indentation
jq --indent 4 . file.json
# Use 2 spaces for indentation (common for JavaScript)
jq --indent 2 . file.json
# Use tabs for indentation
jq --indent '\t' . file.json
Alternative Methods Without External Tools
If you cannot install additional tools like jq, there are several built-in approaches available in most Unix systems.
Using Python’s json.tool
Python is typically available on most Unix systems and includes a built-in JSON pretty-printer:
# Using Python's json.tool
cat file.json | python -m json.tool
This will automatically format JSON with 4-space indentation. You can customize it by creating a simple Python one-liner:
# Custom indentation (2 spaces)
python -c "import json, sys; print(json.dumps(json.load(sys.stdin), indent=2))"
Using PHP’s JSON Functions
If PHP is available on your system, you can use its JSON pretty-printing capabilities:
# Using PHP with 4-space indentation
php -r 'echo json_encode(json_decode(file_get_contents("php://stdin")), JSON_PRETTY_PRINT);' < file.json
Using json_pp
Some systems come with json_pp (JSON pretty-printer) installed, which is part of Perl:
# Using json_pp
cat file.json | json_pp
Creating a Reusable Shell Script
For repeated use, it’s helpful to create a reusable shell script. Here are several options depending on your preferred method:
jq-based Script
#!/bin/bash
# ppjson.sh - Pretty print JSON using jq
if [ $# -eq 0 ]; then
# Read from stdin
jq .
elif [ $# -eq 1 ]; then
# Process file
if [ -f "$1" ]; then
jq . "$1"
else
echo "Error: File '$1' not found" >&2
exit 1
fi
else
echo "Usage: $0 [json_file]" >&2
echo " or: echo '{\"key\":\"value\"}' | $0" >&2
exit 1
fi
Python-based Script
#!/bin/bash
# ppjson.py - Pretty print JSON using Python
if [ $# -eq 0 ]; then
# Read from stdin
python -m json.tool
elif [ $# -eq 1 ]; then
# Process file
if [ -f "$1" ]; then
python -m json.tool < "$1"
else
echo "Error: File '$1' not found" >&2
exit 1
fi
else
echo "Usage: $0 [json_file]" >&2
echo " or: echo '{\"key\":\"value\"}' | $0" >&2
exit 1
fi
Making Scripts Executable and Accessible
- Save the script to a file (e.g.,
ppjson) - Make it executable:
chmod +x ppjson - Move it to your PATH:
sudo mv ppjson /usr/local/bin/ - Now you can use it anywhere:
ppjson file.jsonorcat file.json | ppjson
Advanced jq Features and Customization
jq offers much more than basic pretty-printing. Here are some advanced features that can enhance your JSON processing workflows.
Colorized Output
jq can colorize its output to make it more readable:
# Enable colorized output (works on most modern terminals)
jq -C . file.json
# Force color even when piping to another command
jq -c . file.json | less -R
Specific Field Pretty Printing
You can pretty-print specific fields rather than the entire JSON:
# Pretty-print only the "data" field
jq '.data' file.json
# Pretty-print with custom indentation for specific field
jq '.data | .[]' file.json --indent 4
Processing JSON from Web APIs
jq works exceptionally well with curl and other command-line HTTP tools:
# Pretty-print JSON from a web API
curl -s https://api.example.com/data | jq .
# Pretty-print with error handling
curl -s https://api.example.com/data | jq . || echo "Invalid JSON received"
Creating JSON Processing Pipelines
You can chain multiple jq operations together:
# Extract, filter, and pretty-print
curl -s https://api.example.com/users | jq '.[] | select(.age > 18) | {name: .name, age: .age}'
Handling Common JSON Formatting Issues
When working with real-world JSON data, you may encounter various formatting challenges.
Handling Invalid JSON
If you’re processing JSON that might be invalid, add error handling:
# Safe jq usage with error checking
if cat file.json | jq . >/dev/null 2>&1; then
cat file.json | jq .
else
echo "Error: Invalid JSON format" >&2
exit 1
fi
Processing Multiple JSON Objects
For files containing multiple JSON objects or arrays:
# Pretty-print each JSON object on separate lines
jq -c '.[]' data.json | while read -r obj; do
echo "$obj" | jq .
done
Handling Large JSON Files
For very large JSON files that might cause memory issues:
# Stream processing for large files (if jq supports streaming)
jq -n --stream 'inputs | select(.[0][-1] != "") | fromstream([select(.[0][-1] != "")])' large.json
Special Characters and Unicode
jq handles Unicode and special characters correctly, but if you need to ensure proper encoding:
# Ensure proper Unicode handling
cat file.json | jq -r '.text' # Raw output for special characters
Performance Considerations
When choosing a JSON pretty-printing method, consider performance implications.
Benchmarking Different Methods
For small to medium JSON files (up to 1MB), all methods perform adequately. For larger files, performance differences become noticeable:
# Time different approaches
time cat large.json | jq .
time cat large.json | python -m json.tool
time cat large.json | json_pp
Memory Usage Considerations
- jq: Generally efficient, but uses more memory for very large files
- Python: Can be memory-intensive for extremely large JSON files
- json_pp: Moderate memory usage, similar to jq
Caching and Optimization
For repeated processing of the same files:
# Create pretty-printed version and cache it
if [ ! -f "file.pretty.json" ] || [ "file.json" -nt "file.pretty.json" ]; then
jq . file.json > file.pretty.json
fi
Choosing the Right Tool
- Use jq: For complex operations, filtering, and when you need advanced features
- Use Python: When jq is unavailable and you need reliable pretty-printing
- Use built-in tools: When you cannot install anything and JSON is simple
Conclusion
Pretty-printing JSON in shell scripts is straightforward with the right tools. Here are the key takeaways:
- jq is the recommended tool for JSON processing in shell scripts, offering both simplicity and powerful features
- Alternative methods exist using Python’s
json.tool, PHP, orjson_ppwhen external tools aren’t available - Create reusable scripts to make JSON formatting easily accessible across your development workflow
- Handle edge cases like invalid JSON, large files, and special characters appropriately
- Consider performance when choosing between different methods for your specific use case
For most developers, installing and using jq provides the best combination of features, performance, and ease of use. Start with basic pretty-printing and gradually explore more advanced filtering and transformation capabilities as your needs grow.
Sources
- Stack Overflow - How can I pretty-print JSON in a shell script?
- Nick Janetakis - Pretty Print JSON in Your Terminal with jq or Python
- Linode Docs - How to Use JQ to Process JSON on the Command Line
- Unix & Linux Stack Exchange - How to prettyprint json using jq standalone?
- thanoskoutr - Pretty Print JSON in Linux Terminal
- TecAdmin - Practical Examples of JSON Processing with JQ in Linux
- Baeldung - Guide to Linux jq Command for JSON Processing
- Shapeshed - JSON on the command line with jq