Чтобы быстро извлечь значения для определенного ключа, мне лично нравится использовать «grep -o», который возвращает только совпадение с регулярным выражением. Например, чтобы получить текстовое поле из твитов, что-то вроде:
grep -Po '"text":.*?[^\\]",' tweets.json
Это регулярное выражение более надежно, чем вы думаете; например, он прекрасно работает со строками, имеющими запятые и экранированные кавычки внутри них. Я думаю, немного проделав работу, вы могли бы сделать такую, которая действительно гарантированно извлечет значение, если оно атомарное. (Если у него есть вложенность, то, конечно, регулярное выражение не может этого сделать.)
А для дальнейшей очистки (хотя и сохраняя исходное экранирование строки) вы можете использовать что-то вроде: | perl -pe 's/"text"://; s/^"//; s/",$//'
. (Я сделал это для этого анализа .)
Всем ненавистникам, которые настаивают на том, что вы должны использовать настоящий анализатор JSON - да, это важно для правильности, но
- Чтобы провести действительно быстрый анализ, например, подсчет значений для проверки ошибок очистки данных или общее представление о данных, вывести что-либо в командную строку быстрее. Открытие редактора для написания сценария отвлекает.
grep -o
на несколько порядков быстрее, чем стандартная библиотека Python json
, по крайней мере при выполнении этого для твитов (каждый размером ~ 2 КБ). Я не уверен, что это только потому, что json
медленный (я должен сравнить с yajl когда-нибудь); но в принципе регулярное выражение должно быть быстрее, поскольку оно имеет конечное состояние и гораздо более оптимизируемое, а не синтаксический анализатор, который должен поддерживать рекурсию, и в этом случае тратит много деревьев построения ЦП для структур, которые вас не интересуют. (Если бы кто-то написал преобразователь конечного состояния, который выполнял правильный (ограниченный по глубине) анализ JSON, это было бы здорово! Тем временем у нас есть «grep -o».)
Для написания поддерживаемого кода я всегда использую настоящую библиотеку синтаксического анализа. Я не пробовал jsawk , но если бы он работал хорошо, это бы указывало на пункт 1.
Последнее, причудливое решение: я написал скрипт, который использует Python json
и извлекает нужные ключи в столбцы, разделенные табуляцией; затем я передаю через оболочку awk
, которая разрешает именованный доступ к столбцам. Здесь: сценарии json2tsv и tsvawk . Так что для этого примера это будет:
json2tsv id text < tweets.json | tsvawk '{print "tweet " $id " is: " $text}'
Этот подход не обращается к # 2, более неэффективен, чем отдельный скрипт Python, и он немного хрупок: он заставляет нормализовать переводы строк и табуляции в строковых значениях, чтобы хорошо играть с представлением awk в поле / записи с разделителями мир. Но он позволяет вам оставаться в командной строке с большей точностью, чем grep -o
.