Как я могу красиво напечатать JSON в сценарии оболочки?

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

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

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

... в нечто вроде этого:

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

63 ответа

С Python 2.6+ вы можете просто сделать:

echo '{"foo": "lorem", "bar": "ipsum"}' | python -m json.tool

или, если JSON находится в файле, вы можете сделать:

python -m json.tool my_json.json

если JSON взят из интернет-источника, такого как API, вы можете использовать

curl http://my_url/ | python -m json.tool

Для удобства во всех этих случаях вы можете сделать псевдоним:

alias prettyjson='python -m json.tool'

Для еще большего удобства с небольшим количеством печатания, чтобы подготовить это:

prettyjson_s() {
    echo "$1" | python -m json.tool
}

prettyjson_f() {
    python -m json.tool "$1"
}

prettyjson_w() {
    curl "$1" | python -m json.tool
}

для всех вышеперечисленных случаев. Вы можете положить это в .bashrc и он будет доступен каждый раз в оболочке. Вызвать его как prettyjson_s '{"foo": "lorem", "bar": "ipsum"}',

Ты можешь использовать: jq

Он очень прост в использовании и отлично работает! Он может обрабатывать очень большие структуры JSON, включая потоки. Вы можете найти их уроки здесь.

Вот пример:

$ jq . <<< '{ "foo": "lorem", "bar": "ipsum" }'
{
  "bar": "ipsum",
  "foo": "lorem"
}

Или другими словами:

$ echo '{ "foo": "lorem", "bar": "ipsum" }' | jq .
{
  "bar": "ipsum",
  "foo": "lorem"
}

Я использую аргумент "пробел" JSON.stringify красиво распечатать JSON в JavaScript.

Примеры:

// Indent with 4 spaces
JSON.stringify({"foo":"lorem","bar":"ipsum"}, null, 4);

// Indent with tabs
JSON.stringify({"foo":"lorem","bar":"ipsum"}, null, '\t');

Из командной строки Unix с nodejs, указав json в командной строке:

$ node -e "console.log(JSON.stringify(JSON.parse(process.argv[1]), null, '\t'));" \
  '{"foo":"lorem","bar":"ipsum"}'

Возвращает:

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

Из командной строки Unix с Node.js, указав имя файла, содержащее JSON, и используя отступ из четырех пробелов:

$ node -e "console.log(JSON.stringify(JSON.parse(require('fs') \
      .readFileSync(process.argv[1])), null, 4));"  filename.json

Используя трубу:

echo '{"foo": "lorem", "bar": "ipsum"}' | node -e \
"\
 s=process.openStdin();\
 d=[];\
 s.on('data',function(c){\
   d.push(c);\
 });\
 s.on('end',function(){\
   console.log(JSON.stringify(JSON.parse(d.join('')),null,2));\
 });\
"

Я написал инструмент, который имеет один из лучших доступных форматировщиков "умных пробелов". Он производит более читаемый и менее подробный вывод, чем большинство других опций здесь.

подчеркивание-кли

Вот как выглядит "умный пробел":

Я могу быть немного предвзятым, но это потрясающий инструмент для печати и манипулирования данными JSON из командной строки. Он очень удобен в использовании и имеет обширную справку / документацию для командной строки. Это швейцарский армейский нож, которым я пользуюсь для выполнения 1001 разных небольших задач, что было бы удивительно раздражать, если бы я делал по-другому.

Последний вариант использования: Chrome, консоль Dev, вкладка Network, экспорт всего в виде файла HAR, "cat site.har | underscore select '.url' --outfmt text | grep mydomain"; теперь у меня есть хронологически упорядоченный список всех ссылок URL, сделанных во время загрузки сайта моей компании.

Красивая печать легко:

underscore -i data.json print

То же самое:

cat data.json | underscore print

То же самое, более явно:

cat data.json | underscore print --outfmt pretty

Этот инструмент является моим текущим страстным проектом, поэтому если у вас есть какие-либо пожелания, есть большая вероятность, что я отвечу на них.

Я обычно просто делаю:

echo '{"test":1,"test2":2}' | python -mjson.tool

И для извлечения выбранных данных (в данном случае это значение "test"):

echo '{"test":1,"test2":2}' | python -c 'import sys,json;data=json.loads(sys.stdin.read()); print data["test"]'

Если данные JSON находятся в файле:

python -mjson.tool filename.json

Если вы хотите сделать все это сразу curl в командной строке с помощью токена аутентификации:

curl -X GET -H "Authorization: Token wef4fwef54te4t5teerdfgghrtgdg53" http://testsite/api/ | python -mjson.tool

Если вы используете npm и Node.js, вы можете сделать npm install -g json а затем передать команду через json, Делать json -h чтобы получить все варианты. Он также может извлечь определенные поля и раскрасить вывод с помощью -i,

curl -s http://search.twitter.com/search.json?q=node.js | json

Это не так просто с нативным способом с помощью инструментов jq.

Например:

cat xxx | jq .

Благодаря очень полезным указателям Дж.Ф. Себастьяна, вот немного улучшенный сценарий, который я придумал:

#!/usr/bin/python

"""
Convert JSON data to human-readable form.

Usage:
  prettyJSON.py inputFile [outputFile]
"""

import sys
import simplejson as json


def main(args):
    try:
        if args[1] == '-':
            inputFile = sys.stdin
        else:
            inputFile = open(args[1])
        input = json.load(inputFile)
        inputFile.close()
    except IndexError:
        usage()
        return False
    if len(args) < 3:
        print json.dumps(input, sort_keys = False, indent = 4)
    else:
        outputFile = open(args[2], "w")
        json.dump(input, outputFile, sort_keys = False, indent = 4)
        outputFile.close()
    return True


def usage():
    print __doc__


if __name__ == "__main__":
    sys.exit(not main(sys.argv))

Ванильный баш

Простой скрипт Bash (grep/awk) для красивой JSON-печати без сторонней установки:

json_pretty.sh

#/bin/bash

grep -Eo '"[^"]*" *(: *([0-9]*|"[^"]*")[^{}\["]*|,)?|[^"\]\[\}\{]*|\{|\},?|\[|\],?|[0-9 ]*,?' | awk '{if ($0 ~ /^[}\]]/ ) offset-=4; printf "%*c%s\n", offset, " ", $0; if ($0 ~ /^[{\[]/) offset+=4}'

Примеры:

1) Читайте файл и печатайте в консоли

cat file.json | json_pretty.sh

2) Использовать с Windows GIT Bash из файла в файл (на основе UTF8):

cat fileIn.json |sh.exe json_pretty.sh > fileOut.json

С Perl используйте модуль CPAN JSON::XS, Устанавливает инструмент командной строки json_xs,

Проверка:

json_xs -t null < myfile.json

Украсьте файл JSON src.json в pretty.json:

< src.json json_xs > pretty.json

Если у вас нет json_xs, пытаться json_pp, "pp" для "чистого perl" - инструмент реализован только на Perl, без привязки к внешней библиотеке C (что и обозначает XS, Perl "Extension System").

Вот как я это делаю:

curl yourUri | json_pp

Это сокращает код и выполняет работу.

На *nix чтение из стандартного ввода и запись в стандартный вывод работает лучше:

#!/usr/bin/env python
"""
Convert JSON data to human-readable form.

(Reads from stdin and writes to stdout)
"""

import sys
try:
    import simplejson as json
except:
    import json

print json.dumps(json.loads(sys.stdin.read()), indent=4)
sys.exit(0)

Поместите это в файл (я назвал мой "prettyJSON" после AnC) в вашем PATH и chmod +x это, и ты хорошо идти.

JSON Ruby Gem поставляется со сценарием оболочки для предварительной настройки JSON:

sudo gem install json
echo '{ "foo": "bar" }' | prettify_json.rb

Скрипт загрузки: http://gist.github.com/3738968

$ echo '{ "foo": "lorem", "bar": "ipsum" }' \
> | python -c'import fileinput, json;
> print(json.dumps(json.loads("".join(fileinput.input())),
>                  sort_keys=True, indent=4))'
{
    "bar": "ipsum",
    "foo": "lorem"
}

ПРИМЕЧАНИЕ: это не способ сделать это.

То же самое в Perl:

$ cat json.txt \
> | perl -0007 -MJSON -nE'say to_json(from_json($_, {allow_nonref=>1}), 
>                                     {pretty=>1})'
{
   "bar" : "ipsum",
   "foo" : "lorem"
}

Примечание 2: если вы запускаете

echo '{ "Düsseldorf": "lorem", "bar": "ipsum" }' \
| python -c'import fileinput, json;
print(json.dumps(json.loads("".join(fileinput.input())),
                 sort_keys=True, indent=4))'

хорошо читаемое слово становится \u закодированным

{
    "D\u00fcsseldorf": "lorem", 
    "bar": "ipsum"
}

Если остальная часть вашего конвейера будет корректно обрабатывать Unicode, и вы хотите, чтобы ваш JSON также был дружественным к человеку, просто используйте ensure_ascii=False

echo '{ "Düsseldorf": "lorem", "bar": "ipsum" }' \
| python -c'import fileinput, json;
print json.dumps(json.loads("".join(fileinput.input())),
                 sort_keys=True, indent=4, ensure_ascii=False)'

и вы получите:

{
    "Düsseldorf": "lorem", 
    "bar": "ipsum"
}

ОБНОВЛЕНИЕ Я использую jq Теперь, как предложено в другом ответе. Он чрезвычайно эффективен при фильтрации JSON, но, по своей сути, также является отличным способом печати JSON для просмотра.

jsonpp - очень приятный принтер для командной строки.

Из README:

Довольно распечатайте ответы веб-сервисов примерно так:

curl -s -L http://<!---->t.co/tYTq5Pu | jsonpp

и создайте красивые файлы на вашем диске:

jsonpp data/long_malformed.json

Если вы работаете в Mac OS X, вы можете brew install jsonpp, Если нет, вы можете просто скопировать двоичный файл куда-нибудь $PATH,

Пытаться pjson, У него есть цвета!

echo '{

Установите его с pip:

⚡ pip install pjson

А затем передать любой JSON-контент в pjson,

вам нужно только использовать jq. Если jq не установлен, вам нужно сначала установить jq.

      sudo apt-get update
sudo apt-get install jq

После установки jq нужно использовать только jq

      echo '{ "foo": "lorem", "bar": "ipsum" }' | jq

Результат выглядит как

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

Или с Руби:

echo '{ "foo": "lorem", "bar": "ipsum" }' | ruby -r json -e 'jj JSON.parse gets'
echo "{ \"foo\": \"lorem\", \"bar\": \"ipsum\" }"|python -m json.tool

Вы можете использовать эту простую команду для достижения результата.

Я использую jshon, чтобы делать именно то, что вы описываете. Просто беги:

echo $COMPACTED_JSON_TEXT | jshon

Вы также можете передавать аргументы для преобразования данных JSON.

Проверьте Jazor. Это простой анализатор командной строки JSON, написанный на Ruby.

gem install jazor
jazor --help

JSONLint имеет реализацию с открытым исходным кодом на github, которую можно использовать в командной строке или включить в проект node.js.

npm install jsonlint -g

а потом

jsonlint -p myfile.json

или же

curl -s "http://api.twitter.com/1/users/show/user.json" | jsonlint | less

Просто передайте вывод jq .,

Пример:

twurl -H ads-api.twitter.com '.......' | jq .

Вы можете просто использовать стандартные инструменты, такие как jq или json_pp.

echo '{ "foo": "lorem", "bar": "ipsum" }' | json_pp

или

echo '{ "foo": "lorem", "bar": "ipsum" }' | jq

оба преобразуют вывод, как показано ниже (jq еще более красочен):

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

Огромным преимуществом jq является то, что он может сделать НАМНОГО больше, если вы хотите проанализировать и обработать json.

Pygmentize

Я комбинирую Python's json.tool с pygmentize:

echo '{"foo": "bar"}' | python -m json.tool | pygmentize -g

Есть несколько альтернатив пигментированию, которые перечислены в моем ответе.

Вот живая демонстрация:

демонстрация

С Perl, если вы установите JSON::PP из CPAN, вы получите команду json_pp. Кража примера из B Bycroft вы получите:

[pdurbin@beamish ~]$ echo '{"foo": "lorem", "bar": "ipsum"}' | json_pp
{
   "bar" : "ipsum",
   "foo" : "lorem"
}

Стоит отметить, что json_pp поставляется с предварительно установленной Ubuntu 12.04 (как минимум) и Debian в /usr/bin/json_pp

Я рекомендую использовать утилиту командной строки json_xs, которая включена в модуль perl JSON:: XS. JSON:: XS - это модуль Perl для сериализации / десериализации JSON, на компьютере с Debian или Ubuntu вы можете установить его следующим образом:

sudo apt-get install libjson-xs-perl

Это очевидно также доступно на CPAN.

Чтобы использовать его для форматирования JSON, полученного из URL, вы можете использовать curl или wget следующим образом:

$ curl -s http://page.that.serves.json.com/json/ | json_xs

или это:

$ wget -q -O - http://page.that.serves.json.com/json/ | json_xs

и отформатировать JSON, содержащийся в файле, вы можете сделать это:

$ json_xs < file-full-of.json

Чтобы переформатировать как YAML, который некоторые люди считают более понятным для человека, чем JSON:

$ json_xs -t yaml < file-full-of.json

jj работает очень быстро, может экономно обрабатывать огромные JSON-документы, не работает с действительными числами JSON и прост в использовании, например:

jj -p # for reading from STDIN

или же

jj -p -i input.json

Он (2018) все еще довольно новый, поэтому, возможно, он не будет обрабатывать недействительный JSON, как вы ожидаете, но его легко установить на основные платформы.

bat это cat клон с подсветкой синтаксиса: https://github.com/sharkdp/bat

Пример:

echo '{"bignum":1e1000'} | bat -p -l json

-p будет выводить без заголовков, и -l будет явно указывать язык.

Он имеет раскраску и форматирование для json и не имеет проблем, отмеченных в этом комментарии: Как я могу красиво напечатать JSON в (Unix) сценарии оболочки?

Когда у вас установлен узел в вашей системе, работает следующее.

      echo '{"test":1,"test2":2}' | npx json

{
  "test": 1,
  "test2": 2
}
Другие вопросы по тегам