jq에 "현재" 키 표시

jq에 "현재" 키 표시

예를 들어 다음과 같은 사용자 이름 사전이 있습니다.

"userinfo": { "alice": { "key1": 1, "key2": 2}, "bob": { "key1": 11, "key2": 22}, ... }

사용자 이름과 일부 값이 포함된 테이블 텍스트를 표시하고 싶습니다.

alice 1 2
bob 11 22

사용자 이름을 첫 번째 열에 넣거나 값을 이후 열로 가져오는 것은 쉽지만 동일한 명령에서 사용자 이름과 그 아래 값을 가져오는 .info[]|[.key1,.key2]방법을 모르겠습니다 . 여러 번 실행하고 출력을 붙여넣는 등 jq어리석은 일을 하지 않으려고 노력하고 있습니다 .jq

답변1

이 작업을 수행하려면 다음 명령을 사용할 수 있습니다.

jq -r '.userinfo | to_entries[] | [.key, .value.key1, .value.key2] | @tsv'

먼저 데이터를 entries참조할 수 있도록 변환한 다음 원하는 값으로 를 생성하고 마지막으로 연산자를 사용하여 출력 list으로 변환합니다 . 다른 형식으로 만들고 싶다면 자세한 내용을 읽어보세요.tab-seperated-values@tsv여기.

또한 해당 플래그를 사용하여 원시 출력을 얻습니다. 그렇지 않으면 해당 문자를 -r얻게 됩니다 . :)"\t"


@님의 댓글0 돌 0: 알 수 없는 수의 키*가 있는 경우 [ .key, .value[] ]다음을 사용하여 모두 얻을 수 있습니다.

답변2

$ jq -r '.userinfo | keys[] as $k | [ $k, .[$k][] ] | @tsv' file
alice   1       2
bob     11      22

file여기서는 입력이 유효한 JSON 문서라고 가정합니다 . 예를 들면 다음과 같습니다.

{
  "userinfo": {
    "alice": {
      "key1": 1,
      "key2": 2
    },
    "bob": {
      "key1": 11,
      "key2": 22
    }
  }
}

이 표현식은 최상위 개체를 jq선택한 다음 해당 개체의 키를 반복하며 각 키는 내부 변수에 할당됩니다 . 특히 모든 키(사용자 이름)에 대한 반복이 발생합니다 .userinfo$k[]keys[]

각 반복마다 배열이 구성됩니다 [ $k, .[$k][] ]. 즉, 키 자체로 구성된 배열과 해당 특정 키와 관련된 객체의 값이 뒤따릅니다 userinfo(아래 키가 무엇 .[$k]인지 또는 키가 몇 개인지에 관계없이 무시합니다. 키 key1key2그 자체).

@tsv생성된 배열은 연산자 에 전달되어 탭으로 구분된 레코드로 출력됩니다.

이를 이해하기 위해 각 객체의 키가 동일한 방식으로 정렬되어 있다고 가정해 보겠습니다 userinfo. 그렇지 않은 경우 jq -S .먼저 데이터를 전달하여 키를 정렬해야 할 수도 있습니다. 하위 객체에 서로 다른 키 세트가 있는 경우(일부는 a가 있고 key3일부는 누락될 수 있음 key1) 출력의 필드에 헤더가 없고 표시도 없기 때문에 출력이 여전히 의미가 없을 가능성이 높습니다. 그 뭔가가 하나에 있습니다.

name좀 더 복잡한 표현식을 사용하여 하위 개체의 키 이름을 기반으로 각 필드의 제목을 생성할 수 있습니다(사용자 이름 필드의 제목으로 사용됨) jq.

(
    [.userinfo[] | keys[]] | unique
) as $h |

# This creates the header using "name" and the unique keys
# from each sub-object:
[ "name", $h[] ],

# Now we need a "double loop" over each user object and
# the unique keys (in $h) that we extracted previously,
# basically: for each user, create an array consisting of 
# the username and the value for each of the keys
# (the inner loop):
[
    .userinfo as $u | 
    $u | 

    # Outer loop:
    keys[] as $k | 
    [
        # The username:
        $k,
        # Inner loop over the $h array, extracting
        # either useful data or nothing depending on
        # whether the key exists in this object.
        ($h[] | $u[$k][.])
  ]
]
| @tsv

정렬되지 않고 누락된/추가 키가 있는 입력 예:

{
  "userinfo": {
    "alice": {
      "key2": 2,
      "key1": 1
    },
    "bob": {
      "key1": 11,
      "key2": 22
    },
    "mallory": {
      "key1": 111,
      "key3": 333
    }
  }
}

산출:

name    key1    key2    key3
alice   1       2
bob     11      22
mallory 111             333

관련 정보