parse json с использованием python

У меня есть файл JSON members.json как members.json ниже.

 { "took": 670, "timed_out": false, "_shards": { "total": 8, "successful": 8, "failed": 0 }, "hits": { "total": 74, "max_score": 1, "hits": [ { "_index": "2000_270_0", "_type": "Medical", "_id": "02:17447847049147026174478:174159", "_score": 1, "_source": { "memberId": "0x7b93910446f91928e23e1043dfdf5bcf", "memberFirstName": "Uri", "memberMiddleName": "Prayag", "memberLastName": "Dubofsky" } }, { "_index": "2000_270_0", "_type": "Medical", "_id": "02:17447847049147026174478:174159", "_score": 1, "_source": { "memberId": "0x7b93910446f91928e23e1043dfdf5bcG", "memberFirstName": "Uri", "memberMiddleName": "Prayag", "memberLastName": "Dubofsky" } } ] } } 

Я хочу разобрать его, используя скрипт bash получить только список field memberId .

Ожидаемый результат:

 memberIds ----------- 0x7b93910446f91928e23e1043dfdf5bcf 0x7b93910446f91928e23e1043dfdf5bcG 

Я попытался добавить следующий код bash + python в .bashrc :

 function getJsonVal() { if [ \( $# -ne 1 \) -o \( -t 0 \) ]; then echo "Usage: getJsonVal 'key' < /tmp/file"; echo " -- or -- "; echo " cat /tmp/input | getJsonVal 'key'"; return; fi; cat | python -c 'import json,sys;obj=json.load(sys.stdin);print obj["'$1'"]'; } 

А потом позвонил:

 $ cat members.json | getJsonVal "memberId" 

Но это бросает:

 Traceback (most recent call last): File "<string>", line 1, in <module> KeyError: 'memberId' 

Справка

https://stackoverflow.com/a/21595107/432903

8 Solutions collect form web for “parse json с использованием python”

Если вы будете использовать:

  cat members.json | python -c 'import json,sys;obj=json.load(sys.stdin);print obj;' 

вы можете проверить структуру вложенного диктатора obj и увидеть, что ваша оригинальная строка должна читать:

 cat members.json | python -c 'import json,sys;obj=json.load(sys.stdin);print obj["hits"]["hits"][0]["_source"]["'$1'"]'; 

к элементу "memberId". Таким образом, вы можете сохранить Python как oneliner.

Если в вложенном элементе «hits» есть несколько элементов, вы можете сделать что-то вроде:

  cat members.json | python -c ' import json, sys obj=json.load(sys.stdin) for y in [x["_source"]["'$1'"] for x in obj["hits"]["hits"]]: print y ' 

Решение Криса Доусона лучше всего найти единственное значение для (уникальных) ключей на любом уровне.

В моем втором примере, который выводит несколько значений, вы сталкиваетесь с ограничениями того, что вы должны попробовать с одним лайнером, и в этот момент я вижу мало причин, чтобы сделать половину обработки в bash и перейти к полному решению Python ,

Другой способ сделать это в bash – использовать jshon . Вот решение вашей проблемы с помощью jshon :

 $ jshon -e hits -e hits -a -e _source -e memberId -u < foo.json 0x7b93910446f91928e23e1043dfdf5bcf 0x7b93910446f91928e23e1043dfdf5bcG 

Параметры -e извлекают значения из json. Параметр -a выполняет итерацию по массиву, а -u декодирует окончательную строку.

Ну, ваш ключ явно не в корне объекта. Попробуйте что-то вроде этого:

 json_key() { python -c ' import json import sys data = json.load(sys.stdin) for key in sys.argv[1:]: try: data = data[key] except TypeError: # This is a list index data = data[int(key)] print(data)' "$@" } 

Это имеет преимущество не просто просто вставлять синтаксис в Python, что может привести к поломке (или, что еще хуже, выполнению произвольного кода).

Затем вы можете вызвать его так:

 json_key hits hits 0 _source memberId < members.json 

Попробуй это:

 $ cat json.txt | python -c 'import sys; import simplejson as json; \ print "\n".join( [i["_source"]["memberId"] for i in json.loads( sys.stdin.read() )["hits"]["hits"]] )' 


Если у вас уже есть pretty printed json, почему бы вам просто не grep его?

 $ cat json.txt | grep memberId "memberId": "0x7b93910446f91928e23e1043dfdf5bcf", "memberId": "0x7b93910446f91928e23e1043dfdf5bcG", 

Вы всегда можете получить довольно печатный формат с помощью python simplejson, чтобы grep его.

 # cat json_raw.txt {"hits": {"hits": [{"_score": 1, "_type": "Medical", "_id": "02:17447847049147026174478:174159", "_source": {"memberLastName": "Dubofsky", "memberMiddleName": "Prayag", "memberId": "0x7b93910446f91928e23e1043dfdf5bcf", "memberFirstName": "Uri"}, "_index": "2000_270_0"}, {"_score": 1, "_type": "Medical", "_id": "02:17447847049147026174478:174159", "_source": {"memberLastName": "Dubofsky", "memberMiddleName": "Prayag", "memberId": "0x7b93910446f91928e23e1043dfdf5bcG", "memberFirstName": "Uri"}, "_index": "2000_270_0"}], "total": 74, "max_score": 1}, "_shards": {"successful": 8, "failed": 0, "total": 8}, "took": 670, "timed_out": false} 

Использовать свалки:

 # cat json_raw.txt | python -c 'import sys; import simplejson as json; \ print json.dumps( json.loads( sys.stdin.read() ), sort_keys=True, indent=4); ' { "_shards": { "failed": 0, "successful": 8, "total": 8 }, "hits": { "hits": [ { "_id": "02:17447847049147026174478:174159", "_index": "2000_270_0", "_score": 1, "_source": { "memberFirstName": "Uri", "memberId": "0x7b93910446f91928e23e1043dfdf5bcf", "memberLastName": "Dubofsky", "memberMiddleName": "Prayag" }, "_type": "Medical" }, { "_id": "02:17447847049147026174478:174159", "_index": "2000_270_0", "_score": 1, "_source": { "memberFirstName": "Uri", "memberId": "0x7b93910446f91928e23e1043dfdf5bcG", "memberLastName": "Dubofsky", "memberMiddleName": "Prayag" }, "_type": "Medical" } ], "max_score": 1, "total": 74 }, "timed_out": false, "took": 670 } 

После этого просто результат grep с шаблоном 'memberId'.

Чтобы быть полностью точным:

 #!/bin/bash filename="$1" cat $filename | python -c 'import sys; import simplejson as json; \ print json.dumps( json.loads( sys.stdin.read() ), sort_keys=True, indent=4)' | \ grep memberId | awk '{print $2}' | sed -e 's/^"//g' | sed -e 's/",$//g' 

Применение:

 $ bash bash.sh json_raw.txt 0x7b93910446f91928e23e1043dfdf5bcf 0x7b93910446f91928e23e1043dfdf5bcG 

Другой альтернативой является jq :

 $ cat members.json | jq -r '.hits|.hits|.[]|._source|.memberId' 0x7b93910446f91928e23e1043dfdf5bcf 0x7b93910446f91928e23e1043dfdf5bcG 

После этого потока я использовал json.tool в python:

python -m json.tool members.json | awk -F'"' '/memberId/{print $4}'

Используя deepdiff, вам не нужно знать точные ключи:

 import json from deepdiff import DeepSearch DeepSearch(json.load(open("members.json", "r")), 'memberId', verbose_level=2)['matched_paths'].values() 

Вот решение bash. 1 мин.

  1. создать файл find_members.sh
  2. добавьте следующую строку в файл + save

echo "memberIds";echo "---------"; cat members.json | grep -E 'memberId'|awk '{print$2}' | cut -d '"' -f2

  1. chmod + x find_members.sh
  2. ./find_members.sh

    memberIds —————- 0x7b93910446f91928e23e1043dfdf5bcf 0x7b93910446f91928e23e1043dfdf5bcG

  • ошибка при подключении удаленного сервера с помощью ssh
  • CentOs 7 Python Issue "-bash: python: команда не найдена"
  • FreeBSD: Как запустить скрипт python в качестве демона?
  • Python 26 pkg отсутствует в CentOS 5
  • YUM python package Что такое diffrence
  • Что включать в RPM, созданный из пакетов python
  • Поймать / диагностировать процесс уничтожения пользователя - Необязательно выходить из системы автоматически
  • Как получить имя пользователя, запустившего `sudo`
  • `man` для языков, отличных от C (например, python, R, javascript и т. д.)?
  • Как установить последнюю версию Python на Debian отдельно или обновить?
  • Как установить python на debian?
  • Linux и Unix - лучшая ОС в мире.