jq - 명령행 JSON 처리기 사용법

jq 는 command line 용 json processor 로 curl 이나 httpie 등의 명령행 http 처리기와 연계하여 JSON 기반의 REST API 를 디버깅할 때 유용한 툴입니다.

설치

jq 는 C 언어로 개발되었으므로 각 플랫폼에 맞게 빌드해서 사용하거나 또는 미리 컴파일된 바이너리를 사용하면 됩니다.

권장하는 방법은 플랫폼에서 제공하는 패키지 관리자를 사용하여 설치하는 것입니다.


RHEL/CentOS

yum install jq


Ubuntu

apt install jq


OS X

brew install jq


Windows

https://github.com/stedolan/jq/releases/download/jq-1.5/jq-win64.exe 를 다운받아서 PATH 가 걸린 폴더에 넣습니다.

사용법

jq tutorial 문서를 참고하세요.


curl 로 github 의 jq 소스에서 최근 5개의 커밋을 확인하는 REST API 호출을 할 경우를 생각해 봅시다.

curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5'


github 가 보내는 응답은 아래와 같이 커밋 이력의 array 가 됩니다. (jsonmate permanent link 참고)

 Click here to expand...
[
    {
        "sha": "0bd7614bd5be91d3209f8fd857637f7c5299849e",
        "commit": {
            "author": {
                "name": "Nicolas Williams",
                "email": "nico@cryptonector.com",
                "date": "2017-04-21T23:40:39Z"
            },
            "committer": {
                "name": "Nicolas Williams",
                "email": "nico@cryptonector.com",
                "date": "2017-04-21T23:41:06Z"
            },
            "message": "Always use jv_mem_*alloc()",
            "tree": {
                "sha": "7307309ede24948fb85b96de510b0f8dcdf3d3bc",
                "url": "https://api.github.com/repos/stedolan/jq/git/trees/7307309ede24948fb85b96de510b0f8dcdf3d3bc"
            },
            "url": "https://api.github.com/repos/stedolan/jq/git/commits/0bd7614bd5be91d3209f8fd857637f7c5299849e",
            "comment_count": "0"
        },
        "url": "https://api.github.com/repos/stedolan/jq/commits/0bd7614bd5be91d3209f8fd857637f7c5299849e",
        "html_url": "https://github.com/stedolan/jq/commit/0bd7614bd5be91d3209f8fd857637f7c5299849e",
        "comments_url": "https://api.github.com/repos/stedolan/jq/commits/0bd7614bd5be91d3209f8fd857637f7c5299849e/comments",
        "author": {
            "login": "nicowilliams",
            "id": "604851",
            "avatar_url": "https://avatars1.githubusercontent.com/u/604851?v=3",
            "gravatar_id": "",
            "url": "https://api.github.com/users/nicowilliams",
            "html_url": "https://github.com/nicowilliams",
            "followers_url": "https://api.github.com/users/nicowilliams/followers",
            "following_url": "https://api.github.com/users/nicowilliams/following{/other_user}",
            "gists_url": "https://api.github.com/users/nicowilliams/gists{/gist_id}",
            "starred_url": "https://api.github.com/users/nicowilliams/starred{/owner}{/repo}",
            "subscriptions_url": "https://api.github.com/users/nicowilliams/subscriptions",
            "organizations_url": "https://api.github.com/users/nicowilliams/orgs",
            "repos_url": "https://api.github.com/users/nicowilliams/repos",
            "events_url": "https://api.github.com/users/nicowilliams/events{/privacy}",
            "received_events_url": "https://api.github.com/users/nicowilliams/received_events",
            "type": "User",
            "site_admin": "false"
        },
        "committer": {
            "login": "nicowilliams",
            "id": "604851",
            "avatar_url": "https://avatars1.githubusercontent.com/u/604851?v=3",
            "gravatar_id": "",
            "url": "https://api.github.com/users/nicowilliams",
            "html_url": "https://github.com/nicowilliams",
            "followers_url": "https://api.github.com/users/nicowilliams/followers",
            "following_url": "https://api.github.com/users/nicowilliams/following{/other_user}",
            "gists_url": "https://api.github.com/users/nicowilliams/gists{/gist_id}",
            "starred_url": "https://api.github.com/users/nicowilliams/starred{/owner}{/repo}",
            "subscriptions_url": "https://api.github.com/users/nicowilliams/subscriptions",
            "organizations_url": "https://api.github.com/users/nicowilliams/orgs",
            "repos_url": "https://api.github.com/users/nicowilliams/repos",
            "events_url": "https://api.github.com/users/nicowilliams/events{/privacy}",
            "received_events_url": "https://api.github.com/users/nicowilliams/received_events",
            "type": "User",
            "site_admin": "false"
        },
        "parents": [
            {
                "sha": "4b4cf789e00f1139940f5f7cd2f2ddafaff3d89e",
                "url": "https://api.github.com/repos/stedolan/jq/commits/4b4cf789e00f1139940f5f7cd2f2ddafaff3d89e",
                "html_url": "https://github.com/stedolan/jq/commit/4b4cf789e00f1139940f5f7cd2f2ddafaff3d89e"
            }
        ]
    },


format

jq 에 '.' 옵션을 사용하면 json 을 보기 좋게 포맷팅해서 표시하게 됩니다. 

curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5' | jq '.'


array 원소 접근

array 의 로 넘어온 commit 목록에서 특정 원소에 접근하려면 .[element_num] 형식의 문법을 사용하면 되며 아래는 두 번째 커밋 정보를 출력합니다.

curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5' | jq '.[1]'

filter 사용

| 연산자로 결과를 필터에 전달하여 처리할 수 있습니다. 아래는 가장 최근 커밋 정보에서 커밋 메시지, 커미터, 날자를 출력합니다.  

 curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5' |jq '.[0] | {message: .commit.message, name: .commit.committer.name, date: .commit.author.date}' 


모든 원소에 filter 적용

숫자 없이 [ ] 연산자를 사용하면 모든 원소를 의미하므로 전체 배열에 필터에 적용할 수 있습니다.

아래는 최근 5개 커밋에서 정보를 뽑아서 각각 object 로 만들어서 리턴합니다.

 curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5' |jq '.[] | {message: .commit.message, name: .commit.committer.name, date: .commit.author.date}' 


결과물 collect

필터를 통해 처리한 개별 결과를 하나로 묶으려면 필터의 결과물을 배열로 만들겠다고 jq 에게 알려주어야 합니다.

[  ] 는 배열을 의미하는 연산자이므로 필터를 감싸주면 결과물을 배열로 만들어 줍니다.


아래는 최근 5개 커밋에서 정보를 뽑아서 배열의 원소로 만들어서 리턴합니다.

 curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5' |jq '[  .[] | {message: .commit.message, name: .commit.committer.name, date: .commit.author.date}  ]' 


같이 보기

Ref