Как я могу красиво напечатать 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
Благодаря очень полезным указателям Дж.Ф. Себастьяна, вот немного улучшенный сценарий, который я придумал:
#!/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
, У него есть цвета!
Установите его с 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
}