NeuroAgent

How to Pretty-Print JSON in Shell Scripts

Learn multiple methods to pretty-print JSON in shell scripts using jq, Python, PHP, and built-in tools. Complete guide with examples for Unix/Linux developers.

Question

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:

json
{ "foo": "lorem", "bar": "ipsum" }

… into something like this:

json
{
    "foo": "lorem",
    "bar": "ipsum"
}
NeuroAgent

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

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:

bash
sudo apt-get install jq

For Red Hat/CentOS/Fedora systems:

bash
sudo yum install jq

For macOS:

bash
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:

bash
# Basic pretty printing
cat file.json | jq .
# Or more concisely:
jq . file.json

This will transform compact JSON like:

json
{"foo":"lorem","bar":"ipsum"}

Into a properly formatted version:

json
{
  "foo": "lorem",
  "bar": "ipsum"
}

Customizing Indentation

You can control the indentation level using the --indent option:

bash
# 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:

bash
# 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:

bash
# 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:

bash
# 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:

bash
# 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

bash
#!/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

bash
#!/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

  1. Save the script to a file (e.g., ppjson)
  2. Make it executable: chmod +x ppjson
  3. Move it to your PATH: sudo mv ppjson /usr/local/bin/
  4. Now you can use it anywhere: ppjson file.json or cat 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:

bash
# 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:

bash
# 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:

bash
# 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:

bash
# 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:

bash
# 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:

bash
# 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:

bash
# 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:

bash
# 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:

bash
# 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:

bash
# 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:

  1. jq is the recommended tool for JSON processing in shell scripts, offering both simplicity and powerful features
  2. Alternative methods exist using Python’s json.tool, PHP, or json_pp when external tools aren’t available
  3. Create reusable scripts to make JSON formatting easily accessible across your development workflow
  4. Handle edge cases like invalid JSON, large files, and special characters appropriately
  5. 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

  1. Stack Overflow - How can I pretty-print JSON in a shell script?
  2. Nick Janetakis - Pretty Print JSON in Your Terminal with jq or Python
  3. Linode Docs - How to Use JQ to Process JSON on the Command Line
  4. Unix & Linux Stack Exchange - How to prettyprint json using jq standalone?
  5. thanoskoutr - Pretty Print JSON in Linux Terminal
  6. TecAdmin - Practical Examples of JSON Processing with JQ in Linux
  7. Baeldung - Guide to Linux jq Command for JSON Processing
  8. Shapeshed - JSON on the command line with jq