본문 바로가기
프로그램 (PHP,Python)

jq 필터로 JSON 정렬하기

by 날으는물고기 2023. 7. 27.

jq 필터로 JSON 정렬하기

jq는 커맨드 라인 상에서 JSON 데이터를 필터링하고 가공하는 강력한 도구입니다. JSON 데이터를 정렬하기 위해서는 다음과 같이 jq 필터를 사용할 수 있습니다.

 

 

예시를 위해 다음과 같은 JSON 데이터가 있다고 가정하겠습니다.

[
  {
    "name": "Alice",
    "age": 30
  },
  {
    "name": "Bob",
    "age": 25
  },
  {
    "name": "Eve",
    "age": 35
  }
]

이름(name)을 기준으로 오름차순 정렬:

cat data.json | jq 'sort_by(.name)'

출력 결과:

[
  {
    "name": "Alice",
    "age": 30
  },
  {
    "name": "Bob",
    "age": 25
  },
  {
    "name": "Eve",
    "age": 35
  }
]

이름(name)을 기준으로 내림차순 정렬:

cat data.json | jq 'sort_by(.name) | reverse'

출력 결과:

[
  {
    "name": "Eve",
    "age": 35
  },
  {
    "name": "Bob",
    "age": 25
  },
  {
    "name": "Alice",
    "age": 30
  }
]

 

to_entries 함수는 jq에서 매우 유용한 함수 중 하나입니다. 이 함수는 객체(object)를 키-값 쌍의 배열로 변환해줍니다. 각 쌍은 key와 value라는 필드를 가지는 객체로 구성됩니다. 이를 활용하면 객체를 배열로 변환하여 필터링, 정렬 또는 매핑하는 작업을 수행할 수 있습니다.

 

다음은 to_entries 함수를 활용하는 예시와 설명입니다.

 

예시를 위해 다음과 같은 JSON 객체가 있다고 가정하겠습니다.

{
  "name": "Alice",
  "age": 30,
  "country": "USA"
}

to_entries 함수를 사용하여 객체를 배열로 변환하기:

echo '{"name": "Alice", "age": 30, "country": "USA"}' | jq 'to_entries'

출력 결과:

[
  {
    "key": "name",
    "value": "Alice"
  },
  {
    "key": "age",
    "value": 30
  },
  {
    "key": "country",
    "value": "USA"
  }
]

to_entries 함수를 사용하면 각 키-값 쌍이 배열 내의 객체로 변환되었습니다.

 

to_entries 함수와 함께 map 함수 사용하기:
map 함수는 배열의 각 항목에 대해 지정된 변환 작업을 수행합니다. 따라서 to_entries 함수와 map 함수를 함께 사용하면 객체의 특정 필드를 선택하는 등의 작업을 수행할 수 있습니다.

echo '{"name": "Alice", "age": 30, "country": "USA"}' | jq 'to_entries | map(select(.key == "age"))'

출력 결과:

[
  {
    "key": "age",
    "value": 30
  }
]

위 예시에서는 map 함수를 사용하여 key가 "age"인 키-값 쌍만 선택했습니다.

 

from_entries 함수를 사용하여 배열을 다시 객체로 변환하기:
from_entries 함수는 to_entries 함수의 반대 작업을 수행합니다. 즉, 키-값 쌍의 배열을 다시 원래의 객체로 복원합니다.

echo '[{"key": "name", "value": "Alice"}, {"key": "age", "value": 30}, {"key": "country", "value": "USA"}]' | jq 'from_entries'

출력 결과:

{
  "name": "Alice",
  "age": 30,
  "country": "USA"
}

from_entries 함수를 사용하여 다시 원래의 객체로 변환되었습니다.

to_entries와 from_entries 함수를 적절하게 활용하면 JSON 데이터를 배열 형태로 가공하거나, 반대로 배열을 다시 객체로 되돌리는 작업 등 다양한 유용한 변환 작업을 수행할 수 있습니다. 이를 통해 데이터를 보다 효율적으로 가공하고 조작할 수 있습니다.

 

walk 함수는 jq에서 재귀적으로 JSON 데이터의 모든 요소를 탐색하며 변환하는 데 사용되는 함수입니다. 이 함수를 사용하면 객체나 배열 내에 중첩된 데이터까지 쉽게 접근하여 원하는 작업을 수행할 수 있습니다.

다음은 walk 함수를 사용하는 예시와 설명입니다.

예시를 위해 다음과 같은 중첩된 JSON 데이터가 있다고 가정하겠습니다.

{
  "name": "Alice",
  "age": 30,
  "address": {
    "city": "New York",
    "zip": "10001"
  },
  "children": [
    { "name": "Bob", "age": 5 },
    { "name": "Eve", "age": 7 }
  ]
}

모든 숫자 필드에 10을 더하기:

echo '{"name": "Alice", "age": 30, "address": {"city": "New York", "zip": "10001"}, "children": [{"name": "Bob", "age": 5}, {"name": "Eve", "age": 7}]}' | jq 'walk(if type == "number" then . + 10 else . end)'

출력 결과:

{
  "name": "Alice",
  "age": 40,
  "address": {
    "city": "New York",
    "zip": "10001"
  },
  "children": [
    {
      "name": "Bob",
      "age": 15
    },
    {
      "name": "Eve",
      "age": 17
    }
  ]
}

위 예시에서는 walk 함수를 사용하여 데이터의 모든 숫자 필드를 선택하고 각 숫자에 10을 더해주었습니다.

모든 문자열 필드의 길이 계산하기:

echo '{"name": "Alice", "age": 30, "address": {"city": "New York", "zip": "10001"}, "children": [{"name": "Bob", "age": 5}, {"name": "Eve", "age": 7}]}' | jq 'walk(if type == "string" then length else . end)'

출력 결과:

{
  "name": 5,
  "age": 30,
  "address": {
    "city": 8,
    "zip": 5
  },
  "children": [
    {
      "name": 3,
      "age": 5
    },
    {
      "name": 3,
      "age": 7
    }
  ]
}

위 예시에서는 walk 함수를 사용하여 데이터의 모든 문자열 필드의 길이를 계산하고, 숫자 필드와 객체, 배열 등은 그대로 유지합니다.

walk 함수를 사용하면 원하는 작업을 수행하기 위해 데이터의 모든 요소에 접근할 수 있습니다. 이를 통해 복잡한 JSON 데이터를 처리하고 변환하는 데 매우 유용하게 활용할 수 있습니다.

 

jq Manual (development version) https://jqlang.github.io/jq/manual/

jq 1.6 Manual https://jqlang.github.io/jq/manual/v1.6/

728x90

댓글