НейроАгент

Как красиво форматировать JSON в shell-скриптах

Узнайте несколько способов красивого форматирования JSON в shell-скриптах с использованием jq, Python, PHP и встроенных инструментов. Полное руководство с примерами для разработчиков Unix/Linux.

Вопрос

Как можно красиво форматировать JSON в shell-скрипте?

Существует ли (Unix) shell-скрипт для форматирования JSON в человекочитаемом виде?

По сути, я хочу преобразовать следующий JSON:

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

… в что-то вроде этого:

json
{
    "foo": "lorem",
    "bar": "ipsum"
}
НейроАгент

Вы можете форматировать JSON в виде читаемого текста в shell-скриптах с помощью нескольких методов, при этом jq является наиболее популярным и мощным инструментом. Простой подход использует cat file.json | jq . или jq . file.json для преобразования компактного JSON в человекочитаемый формат с правильным отступом. Другие альтернативы включают Python’s json.tool, json_pp или возможности форматирования JSON в PHP.

Содержание


Начало работы с jq

jq является наиболее широко используемым и мощным процессором JSON в командной строке, доступным для Unix-систем. Он разработан специально для работы с JSON-данными в shell-окружениях и предлагает отличные возможности форматирования.

Установка jq

Сначала вам нужно установить jq на вашей системе. Процесс установки зависит от вашего дистрибутива Linux:

Для систем Debian/Ubuntu:

bash
sudo apt-get install jq

Для систем Red Hat/CentOS/Fedora:

bash
sudo yum install jq

Для macOS:

bash
brew install jq

Для других систем: Вы можете скачать бинарный файл с официального сайта jq или скомпилировать из исходного кода.

Базовое форматирование

После установки jq делает форматирование JSON невероятно простым:

bash
# Базовое форматирование
cat file.json | jq .
# Или более кратко:
jq . file.json

Это преобразует компактный JSON вида:

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

В правильно отформатированную версию:

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

Настройка отступов

Вы можете контролировать уровень отступа с помощью опции --indent:

bash
# Использовать 4 пробела для отступа
jq --indent 4 . file.json

# Использовать 2 пробела для отступа (обычно для JavaScript)
jq --indent 2 . file.json

# Использовать табуляцию для отступа
jq --indent '\t' . file.json

Альтернативные методы без внешних инструментов

Если вы не можете установить дополнительные инструменты вроде jq, существует несколько встроенных подходов, доступных в большинстве Unix-систем.

Использование Python’s json.tool

Python обычно доступен в большинстве Unix-систем и включает встроенный форматировщик JSON:

bash
# Использование Python's json.tool
cat file.json | python -m json.tool

Это автоматически отформатирует JSON с отступом в 4 пробела. Вы можете настроить его, создав простой Python one-liner:

bash
# Пользовательский отступ (2 пробела)
python -c "import json, sys; print(json.dumps(json.load(sys.stdin), indent=2))"

Использование функций JSON PHP

Если PHP доступен на вашей системе, вы можете использовать его возможности форматирования JSON:

bash
# Использование PHP с отступом в 4 пробела
php -r 'echo json_encode(json_decode(file_get_contents("php://stdin")), JSON_PRETTY_PRINT);' < file.json

Использование json_pp

На некоторых системах установлен json_pp (JSON pretty-printer), который является частью Perl:

bash
# Использование json_pp
cat file.json | json_pp

Создание повторно используемого shell-скрипта

Для повторного использования полезно создать повторно используемый shell-скрипт. Вот несколько вариантов в зависимости от предпочитаемого метода:

Скрипт на основе jq

bash
#!/bin/bash
# ppjson.sh - Форматирование JSON с помощью jq

if [ $# -eq 0 ]; then
    # Чтение из stdin
    jq .
elif [ $# -eq 1 ]; then
    # Обработка файла
    if [ -f "$1" ]; then
        jq . "$1"
    else
        echo "Ошибка: Файл '$1' не найден" >&2
        exit 1
    fi
else
    echo "Использование: $0 [json_file]" >&2
    echo "  или: echo '{\"key\":\"value\"}' | $0" >&2
    exit 1
fi

Скрипт на основе Python

bash
#!/bin/bash
# ppjson.py - Форматирование JSON с помощью Python

if [ $# -eq 0 ]; then
    # Чтение из stdin
    python -m json.tool
elif [ $# -eq 1 ]; then
    # Обработка файла
    if [ -f "$1" ]; then
        python -m json.tool < "$1"
    else
        echo "Ошибка: Файл '$1' не найден" >&2
        exit 1
    fi
else
    echo "Использование: $0 [json_file]" >&2
    echo "  или: echo '{\"key\":\"value\"}' | $0" >&2
    exit 1
fi

Сделать скрипты исполняемыми и доступными

  1. Сохраните скрипт в файл (например, ppjson)
  2. Сделайте его исполняемым: chmod +x ppjson
  3. Переместите его в ваш PATH: sudo mv ppjson /usr/local/bin/
  4. Теперь вы можете использовать его в любом месте: ppjson file.json или cat file.json | ppjson

Расширенные возможности jq и настройка

jq предлагает гораздо больше, чем базовое форматирование. Вот некоторые расширенные возможности, которые могут улучшить ваши рабочие процессы обработки JSON.

Цветной вывод

jq может раскрашивать свой вывод, чтобы сделать его более читаемым:

bash
# Включить цветной вывод (работает в большинстве современных терминалов)
jq -C . file.json

# Принудительно использовать цвет даже при piping в другую команду
jq -c . file.json | less -R

Форматирование конкретных полей

Вы можете форматировать конкретные поля, а не весь JSON:

bash
# Форматировать только поле "data"
jq '.data' file.json

# Форматировать с пользовательским отступом для конкретного поля
jq '.data | .[]' file.json --indent 4

Обработка JSON из веб-API

jq отлично работает с curl и другими командными HTTP-инструментами:

bash
# Форматирование JSON из веб-API
curl -s https://api.example.com/data | jq .

# Форматирование с обработкой ошибок
curl -s https://api.example.com/data | jq . || echo "Получен недопустимый JSON"

Создание конвейеров обработки JSON

Вы можете объединять несколько операций jq вместе:

bash
# Извлечение, фильтрация и форматирование
curl -s https://api.example.com/users | jq '.[] | select(.age > 18) | {name: .name, age: .age}'

Обработка распространенных проблем форматирования JSON

При работе с реальными JSON-данными вы можете столкнуться с различными проблемами форматирования.

Обработка недопустимого JSON

Если вы обрабатываете JSON, который может быть недопустимым, добавьте обработку ошибок:

bash
# Безопасное использование jq с проверкой ошибок
if cat file.json | jq . >/dev/null 2>&1; then
    cat file.json | jq .
else
    echo "Ошибка: Недопустимый формат JSON" >&2
    exit 1
fi

Обработка нескольких JSON-объектов

Для файлов, содержащих несколько JSON-объектов или массивов:

bash
# Форматировать каждый JSON-объект на отдельной строке
jq -c '.[]' data.json | while read -r obj; do
    echo "$obj" | jq .
done

Обработка больших JSON-файлов

Для очень больших JSON-файлов, которые могут вызвать проблемы с памятью:

bash
# Потоковая обработка для больших файлов (если jq поддерживает потоковую обработку)
jq -n --stream 'inputs | select(.[0][-1] != "") | fromstream([select(.[0][-1] != "")])' large.json

Специальные символы и Unicode

jq правильно обрабатывает Unicode и специальные символы, но если вам нужно обеспечить правильное кодирование:

bash
# Обеспечить правильную обработку Unicode
cat file.json | jq -r '.text'  # Сырой вывод для специальных символов

Вопросы производительности

При выборе метода форматирования JSON учитывайте производительность.

Сравнение разных методов

Для небольших и средних JSON-файлов (до 1 МБ) все методы работают адекватно. Для больших файлов различия в производительности становятся заметными:

bash
# Сравнение разных подходов
time cat large.json | jq .
time cat large.json | python -m json.tool
time cat large.json | json_pp

Вопросы использования памяти

  • jq: Как правило, эффективен, но использует больше памяти для очень больших файлов
  • Python: Может быть интенсивным по памяти для чрезвычайно больших JSON-файлов
  • json_pp: Умеренное использование памяти, аналогично jq

Кэширование и оптимизация

Для повторной обработки одних и тех же файлов:

bash
# Создать отформатированную версию и кэшировать ее
if [ ! -f "file.pretty.json" ] || [ "file.json" -nt "file.pretty.json" ]; then
    jq . file.json > file.pretty.json
fi

Выбор правильного инструмента

  • Использовать jq: Для сложных операций, фильтрации и когда вам нужны расширенные возможности
  • Использовать Python: Когда jq недоступен и вам нужно надежное форматирование
  • Использовать встроенные инструменты: Когда вы не можете установить ничего и JSON простой

Заключение

Форматирование JSON в виде читаемого текста в shell-скриптах является простой задачей с правильными инструментами. Вот основные выводы:

  1. jq рекомендуется как инструмент для обработки JSON в shell-скриптах, предлагающий как простоту, так и мощные возможности
  2. Существуют альтернативные методы с использованием Python’s json.tool, PHP или json_pp, когда внешние инструменты недоступны
  3. Создавайте повторно используемые скрипты, чтобы сделать форматирование JSON легко доступным в вашем рабочем процессе разработки
  4. Обрабатывайте крайние случаи, такие как недопустимый JSON, большие файлы и специальные символы, соответствующим образом
  5. Учитывайте производительность при выборе между разными методами для вашего конкретного случая использования

Для большинства разработчиков установка и использование jq обеспечивает наилучшее сочетание возможностей, производительности и простоты использования. Начните с базового форматирования и постепенно исследуйте более расширенные возможности фильтрации и преобразования по мере роста ваших потребностей.

Источники

  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