JSON 배열에서 bash 배열로 하나의 필드를 구문 분석


13

변수에 저장된 객체 목록이 포함 된 JSON 출력이 있습니다. (저는 그 말을하지 않을 수 있습니다)

[
  {
    "item1": "value1",
    "item2": "value2",
    "sub items": [
      {
        "subitem": "subvalue"
      }
    ]
  },
  {
    "item1": "value1_2",
    "item2": "value2_2",
    "sub items_2": [
      {
        "subitem_2": "subvalue_2"
      }
    ]
  }
]

bash 스크립트를 ubuntu 14.04.1에서 실행하려면 배열의 item2에 대한 모든 값이 필요합니다.

전체 결과를 배열로 가져올 수있는 방법을 찾았지만 필요한 항목은 아닙니다.

답변:


17

사용 :

$ cat json
[
  {
    "item1": "value1",
    "item2": "value2",
    "sub items": [
      {
        "subitem": "subvalue"
      }
    ]
  },
  {
    "item1": "value1_2",
    "item2": "value2_2",
    "sub items_2": [
      {
        "subitem_2": "subvalue_2"
      }
    ]
  }
]

암호:

arr=( $(jq -r '.[].item2' json) )
printf '%s\n' "${arr[@]}"

산출:

value2
value2_2

파일 대신 변수 에서이 작업을 수행 할 수 있습니까? 필요하지 않은 경우 과도한 파일 시스템 액세스를 피하려고합니다. 이 배열을 꺼내면 json 출력이 완료됩니다.
JpaytonWPD

1
뭔가 해봤 어?
Gilles Quenot

2
jq . <<< "$json"쉘 (bash)과 관련이 있으며 비특이적 jq

1
괄호 누락 :arr=( $(...) )
Gilles Quenot

4
훌륭한 jq명령이지만 arr=( $(...) )(샘플 입력으로 작동하더라도) 명령 출력을 배열로 구문 분석 하지 마십시오. 임베드 또는 선행 / 트레일 링 공백으로 의도 한대로 작동하지 않으며 실수로 글로브가 발생할 수 있습니다.
mklement0

5

실제로 다음은 버그입니다.

# BAD: Output line of * is replaced with list of local files; can't deal with whitespace
arr=( $( curl -k "$url" | jq -r '.[].item2' ) )

대신 다음을 사용하십시오.

# GOOD (with bash 4.x+), but can't detect failure
readarray -t arr < <(curl -k "$url" | jq -r '.[].item2' )

또는 더 나은 ...

# GOOD (with bash 3.x+), *and* has nonzero status if curl or jq fails
IFS=$'\n' read -r -d '' -a arr \
  < <(set -o pipefail; curl --fail -k "$url" | jq -r '.[].item2' && printf '\0')

2

sputnick 덕분에 나는 이것을 얻었습니다.

arr=( $(curl -k https://localhost/api | jq -r '.[].item2') )

내가 가진 JSON은 API의 출력입니다. wans가 파일 인수를 제거하고 |curl의 출력을 jq로 파이프하기 위해 필요한 모든 작업을 수행했습니다 . 훌륭하게 작동하고 몇 가지 단계를 저장했습니다.


그 코드는 실제로 약간 버그가 있습니다. 결과 요소가있는 경우 어떻게되는지 살펴보십시오 *. 현재 디렉토리의 파일 목록으로 대체됩니다.
Charles Duffy

1
마찬가지로 item2공백이 있는 값은 둘 이상의 배열 요소가됩니다.
찰스 더피

0

쉬운 대안으로, jtc도구 ( https://github.com/ldn-softdev/jtc )를보고 동일한 것을 달성하십시오 (jq의 예에서와 같이).

bash $ arr=( $(jtc -w '<item2>l+0' file.json) )
bash $ printf '%s\n' "${arr[@]}"
"value2"
"value2_2"
bash $ 

-w옵션에 대한 설명 : 각괄호는 <...>전체 json 검색을 지정하고 접미사 l는 값이 아닌 레이블을 검색 +0하도록 지시하고 모든 발생 (첫 번째가 아닌)을 찾도록 지시합니다.


arr=( $(jq ...) )내용이 문자열 분할 및 배열로 채워지기 위해 glob-expand되고있는 한 모든 답변 과 동일한 버그 -줄 바꿈이 아닌 공백이 새 요소를 만들고 glob 표현식처럼 보이는 요소가 파일로 대체됩니다. 식이 일치합니다.
Charles Duffy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.