members.json
아래와 같이 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
스크립트를 사용하여 구문 분석하고 필드 목록 만 가져옵니다 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'
참고
답변
사용하려는 경우 :
$ cat members.json | \
python -c 'import json,sys;obj=json.load(sys.stdin);print obj;'
중첩 된 dictonary의 구조를 검사하고 obj
원래 줄이 다음과 같아야합니다.
$ cat members.json | \
python -c 'import json,sys;obj=json.load(sys.stdin);print obj["hits"]["hits"][0]["_source"]["'$1'"]';
“memberId”요소에 이런 식으로 파이썬을 하나의 라이너로 유지할 수 있습니다.
중첩 된 “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
'
Chris Down의 솔루션은 모든 수준에서 (고유 한) 단일 키를 찾는 데 더 좋습니다.
여러 값을 출력하는 두 번째 예를 통해 하나의 라이너로 시도해야 할 한계에 도달했습니다. .
답변
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)' "$@"
}
이것은 단순히 구문을 파이썬에 주입하는 것만이 아니라 파손 (또는 더 나쁜 임의의 코드 실행)을 유발할 수 있다는 이점이 있습니다.
그런 다음 다음과 같이 호출 할 수 있습니다.
json_key hits hits 0 _source memberId < members.json
답변
또 다른 대안은 jq입니다 .
$ cat members.json | jq -r '.hits|.hits|.[]|._source|.memberId'
0x7b93910446f91928e23e1043dfdf5bcf
0x7b93910446f91928e23e1043dfdf5bcG
답변
이 시도:
$ 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",
항상 simplejson python으로 꽤 인쇄 된 형식을 얻을 수 있습니다 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