Подтвердить что ты не робот

Каковы хорошие инструменты CLI для JSON?

Общая проблема

Хотя я, возможно, диагностирую основную причину события, определяю, сколько пользователей оно затронуло, или извлекаю журналы синхронизации, чтобы оценить влияние недавнего изменения кода на производительность и пропускную способность, мои инструменты остаются grep же: grep, awk, sed, tr, uniq, sort, zcat, tail, head, join и split. Чтобы склеить их все вместе, Unix дает нам каналы, а для более xargs фильтрации у нас есть xargs. Если они меня perl -e, всегда есть perl -e.

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

Аналоги XML

Недавно мне потребовалось пролистать гигабайты XML, чтобы построить гистограмму использования пользователем. Это было достаточно просто с инструментами, которые у меня были, но для более сложных запросов нормальные подходы не работают. Скажем, у меня есть файлы с такими элементами:

<foo user="me">
    <baz key="zoidberg" value="squid" />
    <baz key="leela"    value="cyclops" />
    <baz key="fry"      value="rube" />
</foo>

И скажем, я хочу произвести сопоставление между пользователем и средним числом <baz> на <foo>. Обработка построчно больше не является опцией: мне нужно знать, какого пользователя <foo> я сейчас проверяю, чтобы знать, чье среднее значение для обновления. Любой вид Unix one liner, который выполняет эту задачу, вероятно, будет непостижимым.

К счастью, в области XML у нас есть замечательные технологии, такие как XPath, XQuery и XSLT, которые могут нам помочь.

Ранее я привык использовать замечательный модуль Perl XML::XPath для выполнения запросов, подобных приведенному выше, но после нахождения плагина TextMate, который может запускать выражение XPath для моего текущего окна, я перестал писать одноразовые сценарии Perl для запросить XML. И я только что узнал о XMLStarlet, который устанавливается при наборе этого текста и который я с нетерпением жду в будущем.

Решения JSON?

Так что это приводит меня к моему вопросу: есть ли такие инструменты для JSON? Это всего лишь вопрос времени, когда какая-то задача исследования потребует от меня выполнить аналогичные запросы к файлам JSON, и без таких инструментов, как XPath и XSLT, такая задача будет намного сложнее. Если бы у меня была связка JSON, которая выглядела бы так:

{
  "firstName": "Bender",
  "lastName": "Robot",
  "age": 200,
  "address": {
    "streetAddress": "123",
    "city": "New York",
    "state": "NY",
    "postalCode": "1729"
  },
  "phoneNumber": [
    { "type": "home", "number": "666 555-1234" },
    { "type": "fax", "number": "666 555-4567" }
  ]
}

И я хотел узнать среднее количество телефонных номеров, которые имел каждый человек, я мог сделать что-то вроде этого с XPath:

fn:avg(/fn:count(phoneNumber))

Вопросы

  1. Существуют ли какие-либо инструменты командной строки, которые могут "запрашивать" файлы JSON таким образом?
  2. Если вам нужно обработать кучу файлов JSON в командной строке Unix, какие инструменты вы используете?
  3. Черт, есть ли работа по созданию такого языка запросов для JSON?
  4. Если вы используете такие инструменты в своей повседневной работе, что вам нравится/не нравится в них? Есть ли какие-нибудь ошибки?

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

Смежные вопросы

4b9b3361

Ответ 1

Я только что нашел это:

http://stedolan.github.com/jq/

"jq - это легкий и гибкий процессор командной строки JSON".

2014 обновление:

@user456584 упоминается:

Там также команда 'json' (например, 'jsontool'). Я склонен предпочесть это JQ. Очень UNIX-й. Вот ссылка на проект: github.com/trentm/json -

в README json адресу http://github.com/trentm/json есть длинный список похожих вещей

Ответ 2

Я создал модуль, специально разработанный для манипуляции JSON с командной строкой:

https://github.com/ddopson/underscore-cli

example.png

  • FLEXIBLE. Инструмент "swiss-army-knife" для обработки данных JSON - может использоваться как простой симпатичный принтер или как полноценная Javascript-команда.
  • МОЩНЫЙ - предоставляет полную мощность и функциональность underscore.js(плюс underscore.string)
  • ПРОСТОЙ - упрощает запись однострочных JS, аналогичных использованию "perl -pe"
  • CHAINED. Несколько команд-команд можно связать вместе для создания конвейера обработки данных.
  • MULTI-FORMAT. Богатая поддержка форматов ввода/вывода - довольно печатная, строгая JSON и т.д. [скоро]
  • DOCUMENTED - отличная документация по командной строке с несколькими примерами для каждой команды

Это позволяет вам делать мощные вещи очень легко:

cat earthporn.json | underscore select '.data .title'
# [ 'Fjaðrárgljúfur canyon, Iceland [OC] [683x1024]',
#   'New town, Edinburgh, Scotland [4320 x 3240]',
#   'Sunrise in Bryce Canyon, UT [1120x700] [OC]',
# ...
#   'Kariega Game Reserve, South Africa [3584x2688]',
#   'Valle de la Luna, Chile [OS] [1024x683]',
#   'Frosted trees after a snowstorm in Laax, Switzerland [OC] [1072x712]' ]

cat earthporn.json | underscore select '.data .title' | underscore count
# 25

underscore map --data '[1, 2, 3, 4]' 'value+1'
# prints: [ 2, 3, 4, 5 ]

underscore map --data '{"a": [1, 4], "b": [2, 8]}' '_.max(value)'
# [ 4, 8 ]

echo '{"foo":1, "bar":2}' | underscore map -q 'console.log("key = ", key)'
# key = foo
# key = bar

underscore pluck --data "[{name : 'moe', age : 40}, {name : 'larry', age : 50}, {name : 'curly', age : 60}]" name
# [ 'moe', 'larry', 'curly' ]

underscore keys --data '{name : "larry", age : 50}'
# [ 'name', 'age' ]

underscore reduce --data '[1, 2, 3, 4]' 'total+value'
# 10

Он имеет очень приятную справочную систему с командной строкой и чрезвычайно гибкий. Он хорошо протестирован и готов к использованию; однако я все еще создаю несколько функций, таких как альтернативы для формата ввода/вывода и слияния в моем инструменте обработки шаблонов (см. TODO.md). Если у вас есть какие-либо запросы по функциям, прокомментируйте это сообщение или добавьте проблему в github. Я разработал довольно обширный набор функций, но я был бы рад уделять приоритетное внимание функциям, которые необходимы членам сообщества.

Ответ 3

Один из способов сделать это - преобразовать его в XML. Следующее использует два модуля perl (JSON и XML:: Simple) для преобразования fly-by:

cat test.json | perl -MJSON -MXML::Simple -e 'print XMLout(decode_json(do{local$/;<>}),RootName=>"json")'

который для вашего примера json заканчивается как:

<json age="200" firstName="Bender" lastName="Robot">
  <address city="New York" postalCode="1729" state="NY" streetAddress="123" />
  <phoneNumber number="666 555-1234" type="home" />
  <phoneNumber number="666 555-4567" type="fax" />
</json>

Ответ 4

Взгляните на этот безумный проект jsawk. Это дизайн для фильтрации через вход JSON из командной строки. Проверьте resty, а также для клиента REST командной строки, который можно использовать в конвейерах, которые могут пригодиться.

Ответ 5

Недавно я обнаружил, что JSON легко может быть eval -ed с Python:

$ python -c "json=eval(open('/json.txt').read()); print len(json['phoneNumber'])"
2

Хотя этот метод, очевидно, будет терпеть неудачу, если вход JSON содержит нули.

Ответ 6

Посмотрите f:json-document() из Библиотека FXSL 2.x.

С помощью этой функции очень просто включить JSon и использовать его так же, как... XML.

Например, можно просто написать следующее выражение XPath:

f:json-document($vstrParam)/Students/*[sex = 'Female']

и получить все дочерние элементы Students с помощью sex = 'Female'

Вот полный пример:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 xmlns:f="http://fxsl.sf.net/"
 exclude-result-prefixes="f xs"
 >
 <xsl:import href="../f/func-json-document.xsl"/>

 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:variable name="vstrParam" as="xs:string">
{

  "teacher":{
    "name":
      "Mr Borat",
    "age":
      "35",
    "Nationality":
      "Kazakhstan"
             },


  "Class":{
    "Semester":
      "Summer",
    "Room":
      null,
    "Subject":
      "Politics",
    "Notes":
      "We're happy, you happy?"
           },

  "Students":
    {
      "Smith":
        {"First Name":"Mary","sex":"Female"},
      "Brown":
        {"First Name":"John","sex":"Male"},
      "Jackson":
        {"First Name":"Jackie","sex":"Female"}
    }
    ,


  "Grades":

    {
      "Test":
      [
        {"grade":"A","points":68,"grade":"B","points":25,"grade":"C","points":15},

        {"grade":"C","points":2, "grade":"B","points":29, "grade":"A","points":55},

        {"grade":"C","points":2, "grade":"A","points":72, "grade":"A","points":65}
       ]
    }


}
 </xsl:variable>

 <xsl:template match="/">
    <xsl:sequence select=
     "f:json-document($vstrParam)/Students/*[sex = 'Female']"/>

 </xsl:template>
</xsl:stylesheet>

Когда указанное преобразование применяется к любому XML-документу (игнорируется), получается правильный результат:

<Smith>
   <First_Name>Mary</First_Name>
   <sex>Female</sex>
</Smith>
<Jackson>
   <First_Name>Jackie</First_Name>
   <sex>Female</sex>
</Jackson>

Ответ 7

Существует также интерактивный инструмент терминала - FX

Передайте в FX любой JSON и анонимную функцию для его уменьшения.

$ echo '{...}' | fx [code ...]

Запустите интерактивный режим без передачи аргументов:

$ curl ... | fx

wOQSy.gif

Ответ 8

К счастью, в области XML у нас есть замечательные технологии, такие как XPath, XQuery и XSLT, которые могут нам помочь.
[...]
Так что это приводит меня к моему вопросу: есть ли такие инструменты для JSON?

Если вы спросите меня, Xidel именно то, что вы ищете.

Xidel - это инструмент командной строки для загрузки и извлечения данных со страниц HTML/XML или JSON-API с использованием CSS, XPath 3.0, XQuery 3.0, JSONiq или шаблонных шаблонов. Он также может создавать новые или преобразованные документы XML/HTML/JSON.

Запрос:

xidel -s "input.json" \
-e '
  $json/avg(
    count(
      (phoneNumber)()
    )
  )
'

или же

xidel -s "input.json" -e '$json/avg(count((phoneNumber)()))'

Выход:

2