your programing

jq: 객체에서 키의 서브셋 선택

lovepro 2023. 3. 13. 23:25
반응형

jq: 객체에서 키의 서브셋 선택

배열의 입력 json 키 문자열을 지정하면 원래 개체와 입력 배열에 키가 있었던 항목만 있는 개체를 반환합니다.

해결책이 있지만 우아하지 않다고 생각합니다.{($k):$input[$k]}특히나 투박하게 느껴져...) 그리고 이건 내가 배울 기회야.

jq -n '{"1":"a","2":"b","3":"c"}'   \
    | jq --arg keys '["1","3","4"]' \
    '. as $input 
     | ( $keys | fromjson )
     | map( . as $k
          | $input
          | select(has($k))
          | {($k):$input[$k]}
          )
     | add'

이걸 어떻게 치울지 생각나는 거 없어?

jq를 사용하여 중첩된 JSON 개체에서 선택한 속성을 추출하는 것은 좋은 시작점이라고 생각하지만 제대로 작동하지 않습니다.

내부 점검이 포함된 솔루션:

jq 'with_entries(select([.key] | inside(["key1", "key2"])))'

내부 연산자는 대부분의 시간 동안 작동하지만, 내부 연산자는 부작용이 있고, 때때로 원하지 않는 키를 선택했다고 가정합니다.{ "key1": val1, "key2": val2, "key12": val12 }및 선택 기준inside(["key12"])둘 다 선택됩니다."key1"그리고."key12"

정확한 일치가 필요한 경우 in 연산자를 사용합니다.이렇게 하면 선택됩니다..key2그리고..key12오직.

jq 'with_entries(select(.key | in({"key2":1, "key12":1})))'

in 연산자는 오브젝트(또는 인덱스)에서만 키를 체크하기 때문에exists?어레이에서) 원하는 키를 키로 오브젝트 구문으로 작성해야 하지만 값은 중요하지 않습니다.in 연산자의 사용은 이 목적을 위해 완벽한 것은 아닙니다.Javascript ES6에는 jq 빌트인으로 구현되는 API의 역버전이 포함되어 있는 것을 보고 싶습니다.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes

jq 'with_entries(select(.key | included(["key2", "key12"])))'

물건을 검사하다.keyincluded?배열에서

다음의 필터를 사용할 수 있습니다.

with_entries(
    select(
        .key as $k | any($keys | fromjson[]; . == $k)
    )
)

여기 몇 가지 추가 설명이 있습니다.

입력 객체의 경우{"key1":1, "key2":2, "key3":3}원하는 키 집합에 없는 모든 키를 삭제하려고 합니다.["key1","key3","key4"]

 jq -n --argjson desired_keys '["key1","key3","key4"]'  \
       --argjson input '{"key1":1, "key2":2, "key3":3}' \
    ' $input
    | with_entries(
          select(
              .key == ($desired_keys[])
          )
       )'

with_entries변환하다{"key1":1, "key2":2, "key3":3}는 다음 키 값 쌍의 배열로 구성되어 배열의 select 문을 매핑한 후 결과 배열을 개체로 되돌립니다.

여기 내부 객체가 있습니다.with_entries진술.

[
  {
    "key": "key1",
    "value": 1
  },
  {
    "key": "key2",
    "value": 2
  },
  {
    "key": "key3",
    "value": 3
  }
]

그런 다음 이 배열에서 기준을 충족하는 키를 선택할 수 있습니다.

마법이 일어나는 곳이야이 명령어의 중간에서 무슨 일이 일어나고 있는지 보여 줍니다.다음 명령어는 확장된 값 배열을 가져와 선택할 수 있는 개체 목록으로 변환합니다.

jq -cn '{"key":"key1","value":1}, {"key":"key2","value":2}, {"key":"key3","value":3}
      | select(.key == ("key1", "key3", "key4"))'

이것은 다음과 같은 결과를 낳는다.

{"key":"key1","value":1}
{"key":"key3","value":3}

with entries 명령어는 조금 까다로울 수 있지만 필터를 사용하여 다음과 같이 정의되어 있음을 기억하기 쉽습니다.

def with_entries(f): to_entries|map(f)|from_entries;

이것은 와 같다.

def with_entries(f): [to_entries[] | f] | from_entries;

의 또 은 '입니다.==

다음 명령을 고려합니다.출력은 모든 왼쪽 목록과 오른쪽 목록의 외부에서 생성된 것입니다.

jq -cn '1,2,3| . == (1,1,3)'
true
true
false
false
false
false
false
false
true

그 술어가 select 스테이트먼트에 있는 경우, 그 술어가 참일 때 입력을 유지합니다.여기서도 입력을 복제할 수 있습니다.

jq -cn '1,2,3| select(. == (1,1,3))'
1
1
3

에는 불필요한 몇 가지 .이 두 Jeff의 답변은 Jeff의 경우를 과 같이됩니다.이 두 가지 모두 다음과 같은 전제 하에 해결됩니다.--argjson keys.--arg keys:

with_entries( select( .key as $k | $keys | index($k) ) )

에 「Jq」가 「Jq」가 됩니다.IN:

with_entries(select(.key | IN($keys[])))

입력 배열의 모든 키가 원래 개체에 있는 것이 확실한 경우 개체 구성 바로 가기를 사용할 수 있습니다.

$ echo '{"1":"a","2":"b","3":"c"}' | jq '{"1", "3"}'
{
  "1": "a",
  "3": "c"
}

강제해야 합니다.jq하지 않은 하지 않습니다숫자와 유사하지 않은 키의 경우 따옴표는 필요하지 않습니다.

$ echo '{"key1":"a","key2":"b","key3":"c"}' | jq '{key1, key3}'
{
  "key1": "a",
  "key3": "c"
}

존재하지 않는 키를 추가하면 OP가 원하는 것과 달리 null 값이 생성됩니다.

$ echo '{"1":"a","2":"b","3":"c"}' | jq '{"1", "3", "4"}'
{
  "1": "a",
  "3": "c",
  "4": null
}

그러나 이러한 항목은 걸러질 수 있습니다.

$ echo '{"1":"a","2":"b","3":"c"}' | jq '{"1", "3", "4"} | with_entries(select(.value != null))'
{
  "1": "a",
  "3": "c"
}

이 답변은 OP가 요청한 대로 유효한 입력 json 배열을 수신하지 않지만 존재하는 키를 필터링하는 데 유용합니다.

예: get ": getaud ★★★★★★★★★★★★★★★★★」issJWT는 하다

echo "jwt-as-json" | jq '{aud, iss}'

언급URL : https://stackoverflow.com/questions/29518137/jq-selecting-a-subset-of-keys-from-an-object

반응형