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


Общие Проблемы

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

ранее, я привык использовать замечательный XML::XPath модуль Perl для выполнения запросов, подобных приведенному выше, но после нахождения 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 очень сильны, и достаточно легко писать сценарии для такой обработки, но чтобы действительно позволить людям играть с инструментами оболочки данных, необходимы.

Вопросы

6 51

6 ответов:

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

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

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

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

@user456584 отметил:

есть также команда ' json '(например,'jsontool'). Я, как правило, предпочитаю его над jq. Очень UNIX-y. вот ссылка на проект: github.com/trentm/json -

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

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

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

  • гибкий - инструмент "swiss-army-knife" для обработки данных JSON - может использоваться как простой симпатичный принтер, так и в качестве полноценной командной строки Javascript
  • мощный - раскрывает полную мощность и функциональность подчеркивают.js (плюс подчеркивание.строка)
  • простой - позволяет легко писать на JS один-лайнеры, похожие на "Перл-ЧП"
  • прикованный - несколько вызовов команд могут быть соединены вместе, чтобы создать конвейер обработки данных
  • МУЛЬТИ-ФОРМАТЕ - богатая поддержка форматов ввода / вывода-красивая печать, строгий JSON и т. д. [скоро]
  • документально - отличная командная строка документация с несколькими примерами для каждой команды

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

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. Я разработал довольно обширный набор функций, но я был бы рад определить приоритеты функций, которые необходимы членам сообщества.

один из способов, который вы могли бы сделать, это преобразовать его в 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>

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

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

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

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

посмотреть 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>