jq에서 정렬하지 않고 고유하게 만들기

jq에서 정렬하지 않고 고유하게 만들기

배열 =>["cross", "base", "cross", "dunk"]

정렬하지 않고 중복된 값을 모두 제거하고 싶습니다.

주문하다:jq '. | unique' file.json

산출:["base", "cross", "dunk"]

예상 출력:["cross", "base", "dunk"]

답변1

map({key:.,value:1})|from_entries|keys_unsorted

대안으로 unique실현 가능해 보입니다 .

map배열을 다음으로 변환합니다.

[{"key":"cross","value":1},{"key":"base","value":1},{"key":"cross","value":1},{"key":"dunk","value":1}]

from_entries다음으로 변경하세요.

{"cross":1,"base":1,"dunk":1}

객체의 두 요소는 동일한 키를 가질 수 없으므로 이 시점에서 중복된 요소는 제거됩니다.

keys_unsorted객체의 키를 원래 순서로 반환합니다 .

동일한 원칙을 따르는 더 짧고 간단한 대안:

map({(.):1})|add|keys_unsorted

또는 다음과 같은 보다 일반적인 프로그래밍 언어를 사용할 수 있습니다 perl.

perl -l -0777 -MJSON::PP -MList::Util=uniq -pe '
  $_ = encode_json[uniq @{decode_json $_}]' array.json

-p표현식이 작동 하도록 각 레코드를 array.json가져 오는 sed 모드입니다.$_e

-0777레코드 구분 기호를 불가능한 값으로 설정합니다. 즉, 단 하나의 레코드만 완전한 파일임을 의미합니다( -g최신 버전의 obble 참조 perl).

decode_json $_레코드를 디코딩하고 배열 참조를 반환하고, @{...}목록을 에 전달하고 uniq, [...]결과를 다른 배열 참조에 전달하고 encode_json, 결과를 인쇄합니다 $_(뒤에 개행 문자가 옵니다 -l).

Perl용 JSON 플러그인은 많이 있습니다. JSON::PP(순수 Perl용 PP)는 Perl 코어의 일부이므로 항상 사용할 수 있어야 합니다. JSON::XS는 더 효율적이며 json_xs쉘 스크립트에서 편리하게 사용할 수 있는 기능을 제공합니다.

json_xs -e 'use List::Util "uniq"; $_ = [uniq @$_]' < array.json

이미 익숙하다면 s와 같은 새로운 언어를 perl배울 필요가 없으며 jq알고 있는 언어를 재사용하여 XML, YAML 등과 같은 다른 형식으로 작업할 수 있다는 의미입니다.

답변2

reduce()입력에서 고유 요소의 결과 배열을 작성하는 데 사용됩니다 .

jq 'reduce .[] as $a ([]; if IN(.[]; $a) then . else . += [$a] end)' file.json

이는 기본적으로 의 배열을 반복하여 file.json배열에 이미 존재하지 않는 한 각 요소를 새 배열에 추가합니다.

시험:

$ jq . file.json
[
  "cross",
  "base",
  "cross",
  "dunk"
]
$ jq 'reduce .[] as $a ([]; if IN(.[]; $a) then . else . += [$a] end)' file.json
[
  "cross",
  "base",
  "dunk"
]

관련 정보