jq command

# 커맨드 라인으로 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 쿼리문을 테스트할때 유용하다.

comments:

댓글 쓰기