# 커맨드 라인으로 json data 를 grep 할때 jq 를 사용하면 편하다.
# 맥에서 설치
brew install jq
# centos 에서 설치
yum install jq
# jq 를 이용한 json data grep
# 다음 test.json 있을때
cat > test.json << zzz
{
"name": "bundling",
"version": "1.0.0",
"description": "테스트",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack --watch",
"build": "webpack -p"
},
"keywords": ["lemon", "orange", "apple"],
"author": "",
"license": "ISC",
"dependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"webpack": "^3.10.0"
},
"aaa-bbb": "hypen-test",
"aaa.bbb": "ccc",
"aaa": { "bbb.ccc" : "ddd"},
"arrayobj" : [
{"name":"lemon", "price":200, "desc":"lemon_desc" },
{"name":"apple", "price":300, "desc":"apple_desc" },
{"name":"orange", "price":100, "desc":"orange_desc" }
]
}
zzz
# json 보기
jq . test.json
# json 여부 판단하기
# object, array 면 json
# number, string 등이면 json 이 아닌것으로 판단
jq type test.json
# script object 가져오기
jq .scripts test.json
# cat 과 파이프를 사용해도 된다.
# script object 가져오기
cat test.json | jq .scripts
# 키 이름만 가져오기
jq 'keys' test.json
# dependencies 아래 키 이름만 가져오기
jq '.dependencies|keys' test.json
# script.start 키 값 가져오기
jq .scripts.start test.json
# -r(--raw-output)을 사용하면 "aaa" -> aaa 로 "제거
jq -r .scripts.start test.json
# script 의 start 와 build 필드 값 가져오기
jq '.scripts | "\(.start) \(.build)"' test.json
# keywords arrary 가져오기
jq .keywords test.json
# keywords 두번째 값 가져오기
jq ".keywords[1]" test.json
# keywords 0,1 원소 가져오기
jq ".keywords[:2]" test.json
# keywords 마지막 원소 가져오기
jq ".keywords[-1]" test.json
# keywords 값 순회하기
jq ".keywords[]" test.json
# keywords 원소 개수
jq ".keywords | length" test.json
# keywords 와 arrayobj의 name 가져오기
jq '.keywords, .arrayobj[].name' test.json
# keywords 는 AA 필드명의 값으로 하는 오브젝트 와 arrayobj의 name은 BB 필드명의 값으로 해서 가져오기
jq '{"AA":.keywords}, {"BB":.arrayobj[].name}' test.json
# AA 와 BB 를 하나의 오브젝트로 가져오기
jq '{"AA":.keywords, "BB":.arrayobj[].desc}' test.json
# 쉘 변수는 '$변수' 로 사용
var1="ysoftman"; jq '{"AA":.keywords, "BB":.arrayobj[].desc, "CC":"'${var1}'"}' test.json
# name 필드로 정렬(알파벳 오른 차순)
jq '.arrayobj | sort_by(.name)' test.json
# price 필드로 정렬(숫자 오름 차순)
jq '.arrayobj | sort_by(.price)' test.json
# sort_by 의 입력은 [](배열)이어야 한다.
# 입력 json 이 [] 아니라면 -s(--slurp)로 array 변경해서 처리한다.
jq '.arrayobj[]' test.json | jq -s 'sort_by(.price)'
# 필드명에 . - 등이 있는 경우 ""안에 넣어야 한다.
# 참고로 https://jsonapi.org/format/#document-member-names 을 보면 . 은 필드명을 쓰지 말라고 한다.
jq '."aaa-bbb"' test.json
jq '."aaa.bbb"' test.json
jq '.aaa["bbb.ccc"]' test.json
# 오브젝트(mylist) 리스트 중 특정 필드(name)만 가져오기
jq ".mylist[]".name
# array 요소 중 name 필드값이 특정값인 경우만 가져오기
jq '.arrayobj[] | select(.name == "orange")' test.json
# array 요소 중 name 필드값이 "l" 이 포함된 경우만 가져오기
jq '.arrayobj[] | select(.name | contains ("l"))' test.json
# array 요소 중 name 필드값이 "l" 이 포함 안된 경우만 가져오기
jq '.arrayobj[] | select(.name | contains ("l") | not)' test.json
# addobj 추가하기
jq '. + {"addobj": {"field1": "added_field1", "field2": "added_field2"}}' test.json > test2.json
# author 와 main 필드 값 변경하기
jq '.author="ysoftman" | .main="main.js"' test.json > test2.json
# test2.json 에서 addobj.field2 삭제하기
jq 'del(.addobj.field1)' test2.json
# object list 만들기
echo '[]' | jq '.+[{"a":"aaa","a1":111},{"b":"bbb","b1":222}]'
#####
# mjson 으로 json pretty(indent,들여쓰기) 하기
# mjson 설치
sudo pip install mjson
# 들여쓰기 형태로 보기
echo '{"a":1,"b":2}' | mjson
#####
# jq-1.6 에서 다음과 같이 .[]로 사용하면 문법에러가 발생한다.
cat out.json | jq -r '.status.nodes.[]'
jq: error: syntax error, unexpected '[', expecting FORMAT or QQSTRING_START (Unix shell quoting issues?) at <top-level>, line 1:
.aaa.[]
jq: 1 compile error
# jq-1.6 에서는 다음과 같이 . 없이 사용해야 에러가 발생하지 않는다.
cat out.json | jq -r '.status.node[]'
# 참고로 jq-1.7.1 로 다운받아 실행하면 아래 2가지 방식 모두 된다.
wget https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-linux64
cat out.json | ./jq-linux64 -r '.status.nodes[]'
cat out.json | ./jq-linux64 -r '.status.nodes.[]'
#####
# interactive json viewer
# jq 쿼리문을 테스트할때 유용하다.