jq를 사용하여 json에서 여러 필드를 직렬로 구문 분석 및 표시


237

나는이 Json이

{
    "users": [
        {
            "first": "Stevie",
            "last": "Wonder"
        },
        {
            "first": "Michael",
            "last": "Jackson"
        }
    ]
}

jq를 사용하여 이름과 성을 순차적으로 표시하고 싶습니다. 이렇게-

Stevie Wonder
Michael Jackson

이것은 내가 얼마나 멀리 왔는가-

jq '.users[].first, .users[].last'

그러나 그것은 표시

"Stevie"
"Michael"
"Wonder"
"Jackson"

다음을 주목하십시오-

  1. 내가 원하지 않는 큰 따옴표.
  2. 내가 원하지 않는 캐리지 리턴.
  3. 뒤죽박죽입니다. 내 쿼리는 모든 이름을 먼저 표시 한 다음 모든 성을 표시합니다. 그러나 나는 첫 번째, 첫 번째 마지막 쌍을 원합니다.

답변:



203

더하기 를 사용 하여 문자열을 연결할 수 있습니다.

문자열 은 더 큰 문자열로 결합하여 추가됩니다.

jq '.users[] | .first + " " + .last'

위의 작품 모두 first와는 last문자열입니다. 다른 데이터 유형 (숫자 및 문자열)을 추출하는 경우 동등한 유형으로 변환해야합니다. 이 질문에 대한 해결책을 참조하십시오 . 예를 들어.

jq '.users[] | .first + " " + (.number|tostring)'

41
JSON 인용 부호를 제거하려면 -r 옵션을 사용하여 jq를 호출하십시오 (예 : jq -r '.users [] | 좁은 방 + ""+ .last '
피크

4
+1이지만 유스 케이스의 경우 두 행을 같은 행에 형식화하려고합니다. 이 방법 " "은 숫자에 더할 수 없기 때문에 실패합니다 . Eric의 답변은이 경우에 더 나은 결과를 제공합니다.
Synesso

9
@ Synesso : (.numA|tostring) + " " + (.numB|tostring)작동해야합니다. 또는 대신 문자열 보간을 사용하십시오 "\(.numA) \(.numB)".
LS

내가했을 때 jq '.users[] | .first + " " + .last', 그것은 매우 잘 작동하지만, 값 사이에 줄 바꿈 발생 .first.last. 나는 변경 " ""@"다음을 한 sed 's/@/ /g'출력으로 "홍길동"을 얻기 위해 출력. 이와 같은 것 :jq '.users[] | .first + "@" + .last' | sed 's/@/ /g'
Bloodysock


14

키, 값이 문자열이면 위의 답변이 모두 잘 작동하지만 문자열과 정수를 추가 해야하는 상황이 있습니다 (위의 표현식을 사용하여 jq 오류)

요구 사항 : json 아래에 URL을 작성하려면

pradeep@seleniumframework>curl http://192.168.99.103:8500/v1/catalog/service/apache-443 | jq .[0]
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   251  100   251    0     0   155k      0 --:--:-- --:--:-- --:--:--  245k
{
  "Node": "myconsul",
  "Address": "192.168.99.103",
  "ServiceID": "4ce41e90ede4:compassionate_wozniak:443",
  "ServiceName": "apache-443",
  "ServiceTags": [],
  "ServiceAddress": "",
  "ServicePort": 1443,
  "ServiceEnableTagOverride": false,
  "CreateIndex": 45,
  "ModifyIndex": 45
}

해결책:

curl http://192.168.99.103:8500/v1/catalog/service/apache-443 |
jq '.[0] | "http://" + .Address + ":" + "\(.ServicePort)"'

닫는 괄호를 이스케이프 처리 할 필요가 없으며 오류가 발생합니다.
nymo

2
@nymo : 탈출하지 않습니다. \(...)문자열 보간입니다. 여기서 숫자 .ServicePort를 문자열로 바꿉니다 . +이 솔루션을 더 짧게 만들기 위해 표지판 대신 보간을 사용할 수 있습니다 .
LS

12

이것은 이름의 배열을 생성합니다

> jq '[ .users[] | (.first + " " + .last) ]' ~/test.json

[
  "Stevie Wonder",
  "Michael Jackson"
]

4

나는 이런 식으로 내가 원하는 것에 꽤 가까워졌습니다.

cat my.json | jq '.my.prefix[] | .primary_key + ":", (.sub.prefix[] | "    - " + .sub_key)' | tr -d '"' 

출력은 일반적으로 많은 문제없이 다른 도구로 가져올 수 있도록 yaml에 가깝습니다. (나는 여전히 입력 json의 부분 집합을 basicallt로 내보내는 방법을 찾고 있습니다)


1
내 경우에 이런 종류의 작품은 그냥 | TR -d ' "'끝과 JQ에 -r 옵션을 추가 할 수 있습니다.
user842479

4

내 접근 방식은 (당신의 json 예제가 제대로 구성되지 않았습니다. 추측은 샘플 일뿐입니다)

jq '.Front[] | [.Name,.Out,.In,.Groups] | join("|")'  front.json  > output.txt

이 같은 것을 반환

"new.domain.com-80|8.8.8.8|192.168.2.2:80|192.168.3.29:80 192.168.3.30:80"
"new.domain.com -443|8.8.8.8|192.168.2.2:443|192.168.3.29:443 192.168.3.30:443"

정규식으로 출력을 grep하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.