Хотя я могу диагностировать первопричину события, определяя, на какое количество пользователей она влияла, или дистиллирующий синхронизирующие журналы для оценки производительности и влияния пропускной способности недавнего изменения кода, мои инструменты остаются такими же: grep
, awk
, sed
, tr
, uniq
, sort
, zcat
, tail
, head
, join
, и split
. Для склеивания их всех вместе Unix дает нам каналы, и для знатока, фильтрующего, мы имеем xargs
. Если они приводят меня к сбою, всегда существует perl -e
.
Эти инструменты идеально подходят для обработки файлов CSV, файлов с разделением табуляцией, файлов журнала с предсказуемым форматом строки или файлов с разделенными от запятой парами "ключ-значение". Другими словами, файлы, где каждая строка не имеет рядом ни с каким контекстом.
Я недавно должен был тралить через Гигабайты XML для создания гистограммы из использования пользователем. Это было достаточно легко с инструментами, которые я имел, но для более сложных запросов терпят неудачу нормальные подходы. Скажите, что у меня есть файлы с объектами как это:
И скажем, я хочу произвести отображение от пользователя к среднему количеству
с на
. Обработка линию за линией больше не является опцией: Я должен знать который пользователь
Я в настоящее время осматриваю так, я знаю чье среднее число обновлять. Любой вид Unix один лайнер, который выполняет эту задачу, вероятно, будет непостижимым.
К счастью, на XML-земле, у нас есть замечательные технологии как XPath, XQuery и XSLT для помощи нам.
Ранее, я привык к использованию замечательного XML::XPath
Модуль Perl для выполнения запросов как тот выше, но после нахождения Плагина TextMate, который мог выполнить выражение XPath против моего текущего окна, я прекратил писать одноразовые сценарии Perl для запросов XML. И я просто узнал о XMLStarlet, который устанавливает, поскольку я ввожу это и который я надеюсь использовать в будущем.
Таким образом, это приводит меня к моему вопросу: есть ли какие-либо инструменты как это для 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))
Я замечаю, что все больше сериализации данных делается с помощью JSON, таким образом обрабатывание инструментов как это будет крайне важно при анализе больших дампов данных в будущем. Библиотеки языка для JSON очень сильны, и достаточно легко записать сценарии, чтобы сделать, этот вид обработки, но действительно позволять людям играть вокруг с инструментами оболочки данных необходимы.
Взгляните на f: json-document ()
из библиотеки FXSL 2.x .
Используя эту функцию, очень легко включить JSon и использовать его как ... XML.
Например, можно просто написать следующее выражение XPath:
f:json-document($vstrParam)/Students/*[sex = 'Female']
и получить всех потомков студентов
с 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>
Недавно я обнаружил, что JSON можно легко eval
-ed с помощью Python:
$ python -c "json=eval(open('/json.txt').read()); print len(json['phoneNumber'])"
2
Хотя метод, очевидно, потерпит неудачу, если входной JSON содержит нули.
Один из способов, который вы могли бы сделать, это преобразовать его в XML. Ниже используются два модуля perl (JSON и XML::Simple) для преобразования "на лету":
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>