jq!

jq

커맨드라인 JSON 프로세서 jq json 데이터를 쉽게 조작할 수 있는 CLI 유틸리티

brew install jq
kubectl get nodes -o json 

{
    "items": [
        {
            "status": {
                "addresses": [
                    {
                        "address": "192.168.65.3",
                        "type": "InternalIP"
                    },
                    {
                        "address": "docker-desktop",
                        "type": "Hostname"
                    }
                ]
            }
        }
    ]
}

위 명령어 수행시 아래와 같은 json 데이터가 출력될 경우
파이프라인을 묶어 아래처럼 검색식으로 사용 가능하다.

kubectl get nodes -o json | jq -r '.items[].status.addresses[] | select(.type=="InternalIP") | .address'
192.168.65.3

JSON 안 items 배열 안의 status 객체의 addresses 배열 중 typeInternalIP 객체 중 address 객체를 출력

jq 옵션

–raw-output / -r

jq 로 문자열 출력시 쌍따옴표로 감싸진 문자열이 출력되는데
-r 옵션을 사용하면 이 쌍따옴표를 지운다.

// test.json
[
  {
    "address": "192.168.65.3",
    "type": "InternalIP"
  },
  {
    "address": "docker-desktop",
    "type": "Hostname"
  }
]
cat test.json | jq '.[].address'
"192.168.65.3"
"docker-desktop"

cat test.json | jq -r '.[].address'
192.168.65.3
docker-desktop

–compact-output / -c

한줄로 출력하는 옵션

cat test.json | jq -c '.'
[{"address":"192.168.65.3","type":"InternalIP"},{"address":"docker-desktop","type":"Hostname"}]

–sort-keys / -S

key 를 기준으로 정렬

// sort.json
{
    "b": { "address": "192.168.65.3", "type": "InternalIP" },
    "a": { "address": "docker-desktop", "type": "Hostname"},
    "c": { "address": "8.8.8.8", "type": "DNS" }
}
cat sort.json | jq -S '.'
{
  "a": {
    "address": "docker-desktop",
    "type": "Hostname"
  },
  "b": {
    "address": "192.168.65.3",
    "type": "InternalIP"
  },
  "c": {
    "address": "8.8.8.8",
    "type": "DNS"
  }
}

jq 내장함수

length

입력 받은 객체에 따라 길이를 반환함

// length.json
[
    {
        "address": "docker-desktop",
        "type": "Hostname"
    },
    {
        "address": "192.168.65.3",
        "type": "InternalIP"
    },
    {
        "address": "8.8.8.8",
        "type": "DNS"
    }
]
cat length.json | jq 'length'
3

cat length.json | jq '.[] | length'
2
2
2

sort_by

전체 배열을 받아 객체의 매개변수에 정의된 field 를 기반으로 정렬

// sort_by.json
[
    { "name": "aaa", "age": 23 },
    { "name": "ccc", "age": 23 },
    { "name": "bbb", "age": 23 }
]
cat sort_by.json | jq -c 'sort_by(.name)'
[{"name":"aaa","age":23},{"name":"bbb","age":23},{"name":"ccc","age":23}]

map

java8 stream 의 map 같은 역할, 변환기와 같은 역할이다.

map(x)[.[] | x] 는 같은 연산이라 할 수 있다.

// map.json
[{"name":"c1","age":23},{"name":"h2","age":33},{"name":"h3","age":36}]
cat map.json | jq -c 'map(.age) '
[23,33,36]

cat map.json | jq -c 'map(.age+1)'
[24,34,37]

cat map.json | jq -c '[ .[] | .age ]'
[23,33,36]

cat test.json | jq -c 'map(.age > 30)'
[false,true,true]

객체도 map 함수 입력값이 될 수 있으며 value 값을 순회한다.

echo '{"a":1,"b":2,"c":3}' | jq -c 'map(.+1)'
[2,3,4]

select

boolean_expression 조건문을 이용해 원하는 속성만 출력

[{
    "name": "c1",
    "age": 23
}, {
    "name": "h2",
    "age": 33
}, {
    "name": "h3",
    "age": 36
}]
cat test.json | jq '.[] | select(.age > 30)'
{
  "name": "h2",
  "age": 33
}
{
  "name": "h3",
  "age": 36
}

배열형태의 데이터가 아니기 때문에 map 함수를 사용해 변환하여 배열로 내보낼 수 있다.

cat test.json | jq 'map(select(.age > 30))'
[
  {
    "name": "h2",
    "age": 33
  },
  {
    "name": "h3",
    "age": 36
  }
]

그냥 마지막에 배열로 감싸도 된다.

cat test.json | jq '[ .[] | select(.age > 30)]'
[
  {
    "name": "h2",
    "age": 33
  },
  {
    "name": "h3",
    "age": 36
  }
]

to_entries

key-value 형식으로 데이터를 변경함,

// to_entries.json
[
    { "name": "aaa", "age": 23 },
    { "name": "ccc", "age": 23 },
    { "name": "bbb", "age": 23 }
]
cat to_entries.json | jq 'to_entries'
[
  {
    "key": 0,
    "value": {
      "name": "aaa",
      "age": 23
    }
  },
  {
    "key": 1,
    "value": {
      "name": "ccc",
      "age": 23
    }
  },
  {
    "key": 2,
    "value": {
      "name": "bbb",
      "age": 23
    }
  }
]
{
    "A": { "name": "aaa", "age": 23 },
    "B": { "name": "ccc", "age": 23 },
    "C": { "name": "bbb", "age": 23 }
}
cat test.json | jq 'to_entries'
[
  {
    "key": "A",
    "value": {
      "name": "aaa",
      "age": 23
    }
  },
  {
    "key": "B",
    "value": {
      "name": "ccc",
      "age": 23
    }
  },
  {
    "key": "C",
    "value": {
      "name": "bbb",
      "age": 23
    }
  }
]

assignment

|= Update-assignment

update 연산자라 할 수 있다.

echo '{"a":1,"b":2,"c":3}' | jq -c '.[] |= .+1'
{"a":2,"b":3,"c":4}

카테고리:

업데이트: