Питання Як я можу надрукувати JSON в скрипті оболонки (Unix)?


Чи є скрипт (Unix) для форматування JSON в читабельному вигляді?

В принципі, я хочу це перетворити наступне:

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

... в щось подібне:

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

2503


походження


stackoverflow.com/a/12892039/998291 - shleim
Я загорнув свій власний короткий час назад: github.com/exhuma/braindump/tree/master/jsonformat Код дуже простий, використовуючи власний python json Бібліотека, але я також додав до них жорсткість, щоб отримати підсвічування синтаксису. - exhuma
Наткнувся на це, але потім знайшов Джон Добрий і мені це дуже подобається. Typekit використовує його у своїх прикладах API, тому за ним виникає деяка помилка ^ ^ - Nick Tomlin
Ось публікація в блозі, узагальнюючи деякі з найкращих методів, згаданих у цій темі. Для тих, хто вважає за краще tldr: посилання - PhilYoussef
Будьте обережні: python -m json.tool не завжди дає дійсний JSON. (Підказка: 1e1000) - peak


Відповіді:


З 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"}'.


3740



Ви можете підігнати це на pygmentize -l javascript щоб отримати синтаксичний колірний вихід у командному рядку. Редагувати: Якщо у вас встановлені пігменти, то це є. - Shrikant Sharat
Відмінна відповідь, тільки обережно, я маю з цим це робить сортуйте клавіші на виході - що вам, можливо, знадобиться знати. - Chris Nash
У myy .vimrc "nnoremap <f5>:%! Python -m json.tool <CR>: w <CR>" - imwilsonxu
Схоже, що це звільняє символи Unicode в \ uXXXX, що може бути недоліком. - user1071136
Я створив псевдонім: alias pretty='python -mjson.tool | pygmentize -l json так що я можу просто запустити: command params | pretty. Сподіваюся, це допоможе. PS: Якщо хто-небудь вдасться продовжити це, щоб а) видалити curl-вихід я бачу кожен раз і / або б) НЕ сортувати ключі json; будь ласка, дайте мені знати, буду дуже вдячний. - Clint Eastwood


Ви можете використовувати: jq

Це дуже простий у використанні, і це чудово працює! Він може обробляти дуже великі структури JSON, включаючи потоки. Ви можете знайти їх підручники тут.

Ось приклад:

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

Або іншими словами:

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

690



Існує також а --sort-keys варіант, який корисно в деяких випадках. - Matthew Flaschen
Робота з завитками: curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5' | jq '.' - Hover Ruan
Ця відповідь плутає через неясність <<< оператор. Чому б не просто користуватися echo '{ "foo": "lorem", "bar": "ipsum" }' | jq . для прикладу? - Meekohi
"jq." чудовий, як приємний принтер, але воно поставляється з застереженням: jq (до і включаючи jq версії 1.5) змінить значення дуже великих і дуже малих чисел, оскільки він аналізує числові значення як 64-бітні значення IEEE 754. Щоб перевірити, чи має у вашому улюбленому принтепі те саме питання, спробуйте це значення: 1e1000. Зауважте, що python -mjson.tool погано випробовує цей тест, оскільки він виробляє Infinity, який навіть не є JSON. - peak
@Meekohi альтернативою є "непотрібне використання ехо". Супер щасливі знайшли <<< оператор - саме те, що я шукав. - jchook


Я використовую "космічний" аргумент 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));\
 });\
"

358



Для налагодження об'єктів у Node.js ви повинні використовувати sys.inspect () замість JSON.stringify (). Ось чому: markhansen.co.nz/inspecting-with-json-stringify - Gurpartap Singh
Внизу OP - "скрипт командного рядка * nix", і ця відповідь - це інший контекст. - danorton
@danorton: JS можна використовувати з командного рядка за допомогою node.js та інших подібних рішень. - calvinf
Не потрібно консолі: node -p "JSON.stringify(JSON.parse(process.argv[1]), null, '\t');" також виводить результат до STDOUT. - Julian D.
Це засмучує те, що сценарій відрізняється для імені файлу проти stdin - Lukasz Wiktor


Я написав інструмент, у якому є один з найкращих "розумних пробілів" формати доступні. Він виробляє більш читаний і менш докладний вихід, ніж більшість інших варіантів тут.

підкреслення-cli

Саме це виглядає як "розумне простір":

Я можу бути трохи упередженим, але це чудовий інструмент для друку та обробки даних 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

Цей інструмент є моїм поточним проектом пристрасті, тому, якщо у вас є будь-які запити на функцію, є хороший шанс, що я звернуся до них.


321



Я також оновив мою ~ / .bash_profile, щоб мати наступний рядок: alias underscor = 'підкреслення друку - досить непогано', тепер я можу просто згорнутися example.com/result.json | підкреслити та використовувати підкреслення для іншого форматування - Gal Bracha
Спасибі Дейву! Інструмент хороший! псевдонім pretty-json = "underrsore pretty", а curl output - приємний око - Maxim Ponomarev
Великий інструмент форматування, лише одна примітка: пересилання вихідного файлу (або з -о варіант або з > ) працює лише з підкреслення друку. підкреслимо красиво зберігає файл із вставленими знаками форматування кольорів, наприклад: [32m, [33m, [39m поряд з деякими непридатними для друку перед кожним з них, що робить JSON недійсним. Однак підкреслення друку сам по собі нічого не додає до файлу і робить його форматування чудово. - tiurin
я кохаю jq але це чудово працювало для мого "JSON", який не мав подвійних лапок. - Bluu
@DaveDopson дякую за чудовий інструмент !! Попробуй використати його поруч jsonselect.org/#tryit ... - mycargus


Я зазвичай просто роблю:

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

168



python> = 2,6 потрібно - dim
якщо json має прийти безпосередньо з http api, це також хороший інструмент, реалізований в python: github.com/jkbr/httpі - Florian
Якщо ви встановили вузол (і не заперечуєте вихід YAML стилю), існує також цей пакет: rafeca.com/prettyjson так що ви можете закінчити скручування з | prettyjson - Iolo
Як зазначалося вище, одна з проблем з python -mjson.tool як приємний принтер JSON, це не завжди видає JSON. Наприклад, 1e1000 стає Infinity (чи використовує python 2.x або 3.x). 'jq.' завжди виробляє JSON, але це не гарантує, що саме великі (або дуже малі значення) точно зберігаються. - peak


Завдяки дуже корисним вказівкам Дж. Ф. Себастьяна, ось трохи покращений сценарій, з яким я вигадав:

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

82



Коли значення завантажуються в словник, порядок втрачається: нормальний dict об'єкти не мають певного порядку. Спробуй json.dumps(json.loads('{"b": 1, "a": 2}'), sort_keys=False) і ви побачите, що вони взагалі міняються. Щоб це виправити, імпортуйте OrderedDict і load проходження object_pairs_hook=OrderedDict. - icktoofay
Ви можете змінити скрипт на читання із стандартного вводу за допомогою цього: inputFile = sys.stdin. Це дає змогу перетворювати матеріали на сценарій таким чином: curl http://somewhere.com/foo.json | pp_json.py - Gabe Johnson
І щоб уникнути сортування за допомогою коментарю @ icktoofay, імпортуйте OrderedDict так: from collections import OrderedDict. - Hugo
Дякую @ чиктофау. Це дозволило мені створити наступну функцію vim: com! FormatJSON %!python -c "from collections import OrderedDict; import sys; import json; j = json.load(sys.stdin, object_pairs_hook=OrderedDict); json.dump(j, sys.stdout, sort_keys=False, indent=4, separators=(',', ': '))"  Зверніть увагу, що роздільники повинні бути встановлені як (',', ':'), щоб уникнути додавання пробілів. bugs.python.org/issue16333 - blindsnowmobile
Великий фрагмент! Я використовував sort_keys = True замість цього, тому що я хочу використовувати це для порівняння файлів json, і це працює як чарівність. - JL Peyret


На * nix, читання зі stdin і написання на stdout працює краще:

#!/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" після АНК's відповідь) у вашому PATH і chmod +x це, і ти добре йти.


66



Дійсно, використання stdin / stdout набагато гнучкіше і простіше. Дякую, що вказали на це. - AnC
Для програм, які очікують іменованого файлу, скористайтеся / dev / stdin, так само як і для помилок. - dvogel
FYI fileinput.input() читає з stdin, якщо в командному рядку відсутні файли. Приклад - jfs
fileinput.input () не може добре працювати з файлами, у яких не було нової рядка, в останній раз я перевірив. - Zachary Vance
stdin.read () не може зупинитися ... як я можу зупинити це ??? - xiaoweiz


За допомогою 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, "Extension System" Perl).


65



Схоже, стандарт з Cygwin! - Janus Troelsen
json_pp може використовуватися таким самим способом, і, швидше за все, легко встановлюється у вашій системі (на Debian він знаходиться в пакеті "perl"). - MichielB
FYI, у моїй системі Mac OS X 10.9, json_pp доступний автоматично. - Gregg Williams
Або pp для "досить друку" .. - FliiFe
-t null дав мені null: недійсний формат... але залишити це працювало чудово. Дякую. - Lucas


Якщо ви використовуєте npm та Node.js, ви можете це зробити npm install -g json а потім пропустіть команду json. Зробіть json -h отримати всі варіанти. Він також може витягувати окремі поля та розфарбувати вихід з -i.

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

64



Це, безумовно, моя улюблена відповідь тут. - Jon Deaton


JSON Ruby Gem комплектується скриптом оболонки, щоб виправити JSON:

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

Завантаження сценарію: gist.github.com/3738968


63



Зауважте, що це рішення розшифровує ескізи послідовностей Unicode "\ uxxxx", на відміну від Python one з json.tool. Однак, мабуть, він має обмеження глибини гніздування (nesting of 20 is too deep (JSON::NestingError)) - a3nm
на Ubuntu ви можете зробити: sudo apt-get install ruby-json-pure замість gem install - Janus Troelsen
`` `eric-mbp: ~ ericstob $ sudo gem install json Пароль: Витяг: json-1.7.3.gem (100%) Створення власних розширень. Це може зайняти деякий час ... Успішно встановлений json-1.7.3 1 gem встановлений Встановлення ri документації для json-1.7.3 ... Встановлення RDoc документації для json-1.7.3 ... eric-mbp: ~ ericstob $ prettify_json .rb -bash: prettify_json.rb: команду не знайдено - Eric Hartford
може бути, ви можете опублікувати вміст вашого prettify_json.rb? - Andrew
Ви можете завантажити сценарій, перемістити його на свій ~/bin папка (переконайтеся, що вона знаходиться у вашому PATH), перейменувати prettify_json.rbдо ppj і біжи chmod +x ppj. Тепер ви можете зробити щось подібне curl www.jsonsring.com/something.json | ppj - Uri