Как можно красиво форматировать JSON в shell-скрипте?
Существует ли (Unix) shell-скрипт для форматирования JSON в человекочитаемом виде?
По сути, я хочу преобразовать следующий JSON:
{ "foo": "lorem", "bar": "ipsum" }
… в что-то вроде этого:
{
"foo": "lorem",
"bar": "ipsum"
}
Вы можете форматировать JSON в виде читаемого текста в shell-скриптах с помощью нескольких методов, при этом jq является наиболее популярным и мощным инструментом. Простой подход использует cat file.json | jq . или jq . file.json для преобразования компактного JSON в человекочитаемый формат с правильным отступом. Другие альтернативы включают Python’s json.tool, json_pp или возможности форматирования JSON в PHP.
Содержание
- Начало работы с jq
- Альтернативные методы без внешних инструментов
- Создание повторно используемого shell-скрипта
- Расширенные возможности jq и настройка
- Обработка распространенных проблем форматирования JSON
- Вопросы производительности
Начало работы с jq
jq является наиболее широко используемым и мощным процессором JSON в командной строке, доступным для Unix-систем. Он разработан специально для работы с JSON-данными в shell-окружениях и предлагает отличные возможности форматирования.
Установка jq
Сначала вам нужно установить jq на вашей системе. Процесс установки зависит от вашего дистрибутива Linux:
Для систем Debian/Ubuntu:
sudo apt-get install jq
Для систем Red Hat/CentOS/Fedora:
sudo yum install jq
Для macOS:
brew install jq
Для других систем: Вы можете скачать бинарный файл с официального сайта jq или скомпилировать из исходного кода.
Базовое форматирование
После установки jq делает форматирование JSON невероятно простым:
# Базовое форматирование
cat file.json | jq .
# Или более кратко:
jq . file.json
Это преобразует компактный JSON вида:
{"foo":"lorem","bar":"ipsum"}
В правильно отформатированную версию:
{
"foo": "lorem",
"bar": "ipsum"
}
Настройка отступов
Вы можете контролировать уровень отступа с помощью опции --indent:
# Использовать 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:
# Использование Python's json.tool
cat file.json | python -m json.tool
Это автоматически отформатирует JSON с отступом в 4 пробела. Вы можете настроить его, создав простой Python one-liner:
# Пользовательский отступ (2 пробела)
python -c "import json, sys; print(json.dumps(json.load(sys.stdin), indent=2))"
Использование функций JSON PHP
Если PHP доступен на вашей системе, вы можете использовать его возможности форматирования JSON:
# Использование 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:
# Использование json_pp
cat file.json | json_pp
Создание повторно используемого shell-скрипта
Для повторного использования полезно создать повторно используемый shell-скрипт. Вот несколько вариантов в зависимости от предпочитаемого метода:
Скрипт на основе jq
#!/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
#!/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
Сделать скрипты исполняемыми и доступными
- Сохраните скрипт в файл (например,
ppjson) - Сделайте его исполняемым:
chmod +x ppjson - Переместите его в ваш PATH:
sudo mv ppjson /usr/local/bin/ - Теперь вы можете использовать его в любом месте:
ppjson file.jsonилиcat file.json | ppjson
Расширенные возможности jq и настройка
jq предлагает гораздо больше, чем базовое форматирование. Вот некоторые расширенные возможности, которые могут улучшить ваши рабочие процессы обработки JSON.
Цветной вывод
jq может раскрашивать свой вывод, чтобы сделать его более читаемым:
# Включить цветной вывод (работает в большинстве современных терминалов)
jq -C . file.json
# Принудительно использовать цвет даже при piping в другую команду
jq -c . file.json | less -R
Форматирование конкретных полей
Вы можете форматировать конкретные поля, а не весь JSON:
# Форматировать только поле "data"
jq '.data' file.json
# Форматировать с пользовательским отступом для конкретного поля
jq '.data | .[]' file.json --indent 4
Обработка JSON из веб-API
jq отлично работает с curl и другими командными HTTP-инструментами:
# Форматирование JSON из веб-API
curl -s https://api.example.com/data | jq .
# Форматирование с обработкой ошибок
curl -s https://api.example.com/data | jq . || echo "Получен недопустимый JSON"
Создание конвейеров обработки JSON
Вы можете объединять несколько операций jq вместе:
# Извлечение, фильтрация и форматирование
curl -s https://api.example.com/users | jq '.[] | select(.age > 18) | {name: .name, age: .age}'
Обработка распространенных проблем форматирования JSON
При работе с реальными JSON-данными вы можете столкнуться с различными проблемами форматирования.
Обработка недопустимого JSON
Если вы обрабатываете JSON, который может быть недопустимым, добавьте обработку ошибок:
# Безопасное использование jq с проверкой ошибок
if cat file.json | jq . >/dev/null 2>&1; then
cat file.json | jq .
else
echo "Ошибка: Недопустимый формат JSON" >&2
exit 1
fi
Обработка нескольких JSON-объектов
Для файлов, содержащих несколько JSON-объектов или массивов:
# Форматировать каждый JSON-объект на отдельной строке
jq -c '.[]' data.json | while read -r obj; do
echo "$obj" | jq .
done
Обработка больших JSON-файлов
Для очень больших JSON-файлов, которые могут вызвать проблемы с памятью:
# Потоковая обработка для больших файлов (если jq поддерживает потоковую обработку)
jq -n --stream 'inputs | select(.[0][-1] != "") | fromstream([select(.[0][-1] != "")])' large.json
Специальные символы и Unicode
jq правильно обрабатывает Unicode и специальные символы, но если вам нужно обеспечить правильное кодирование:
# Обеспечить правильную обработку Unicode
cat file.json | jq -r '.text' # Сырой вывод для специальных символов
Вопросы производительности
При выборе метода форматирования JSON учитывайте производительность.
Сравнение разных методов
Для небольших и средних JSON-файлов (до 1 МБ) все методы работают адекватно. Для больших файлов различия в производительности становятся заметными:
# Сравнение разных подходов
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
Кэширование и оптимизация
Для повторной обработки одних и тех же файлов:
# Создать отформатированную версию и кэшировать ее
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-скриптах является простой задачей с правильными инструментами. Вот основные выводы:
- jq рекомендуется как инструмент для обработки JSON в shell-скриптах, предлагающий как простоту, так и мощные возможности
- Существуют альтернативные методы с использованием Python’s
json.tool, PHP илиjson_pp, когда внешние инструменты недоступны - Создавайте повторно используемые скрипты, чтобы сделать форматирование JSON легко доступным в вашем рабочем процессе разработки
- Обрабатывайте крайние случаи, такие как недопустимый JSON, большие файлы и специальные символы, соответствующим образом
- Учитывайте производительность при выборе между разными методами для вашего конкретного случая использования
Для большинства разработчиков установка и использование jq обеспечивает наилучшее сочетание возможностей, производительности и простоты использования. Начните с базового форматирования и постепенно исследуйте более расширенные возможности фильтрации и преобразования по мере роста ваших потребностей.
Источники
- 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