jq를 사용하여 Linux 명령 행에서 JSON 파일을 구문 분석하는 방법

0
1313
Linux PC의 터미널 프롬프트
Fatmawati Achmad Zaenuri / 셔터 스톡

JSON은 웹에서 텍스트 기반 데이터를 전송하는 데 가장 널리 사용되는 형식 중 하나입니다. 어디에나 있고, 당신은 그것을 만날 수밖에 없습니다. Linux 명령 행에서이를 처리하는 방법을 보여줍니다. jq 명령.

JSON과 jq

JSON은 JavaScript Object Notation의 약어입니다. 자체 설명 방식으로 데이터를 일반 텍스트 파일로 인코딩 할 수있는 체계입니다. JSON 파일에는 주석이 없습니다. 내용은 설명이 필요합니다. 각 데이터 값에는 “name”또는 “key”라는 텍스트 문자열이 있습니다. 데이터 값이 무엇인지 알려줍니다. 이를 함께 이름 : 값 쌍 또는 키 : 값 쌍이라고합니다. 콜론 (:)는 키와 값을 구분합니다.

“객체”는 키 : 값 쌍의 모음입니다. JSON 파일에서 객체는 열린 중괄호 ({)로 끝나고 닫는 중괄호 (}). JSON은 정렬 된 값 목록 인 “배열”도 지원합니다. 배열은 여는 괄호 (()로 끝나는 것으로 끝나는 ()).

물론 이러한 간단한 정의로부터 임의의 복잡성이 발생할 수 있습니다. 예를 들어, 객체는 객체 내에 중첩 될 수 있습니다. 객체는 배열을 포함 할 수 있으며, 배열은 객체를 포함 할 수도 있습니다. 모두 개방형 수준의 중첩을 가질 수 있습니다.

그러나 실제로 JSON 데이터의 레이아웃이 복잡하면 데이터 레이아웃 디자인에 재고를 사용해야합니다. 물론 JSON 데이터를 생성하지 않고 사용하려고하면 레이아웃에 대한 언급이 없습니다. 그러한 경우, 불행히도, 당신은 그것을 처리해야합니다.

대부분의 프로그래밍 언어에는 JSON 데이터를 구문 분석 할 수있는 라이브러리 또는 모듈이 있습니다. 슬프게도 Bash 쉘에는 그러한 기능이 없습니다.

그러나 발명의 어머니가 될 필요성은 jq 유틸리티가 탄생했습니다! 와 jqBash 셸에서 JSON을 쉽게 구문 분석 할 수 있습니다. 또한 잘 설계되고 우아한 JSON으로 작업해야하는지 또는 악몽으로 만든 작업이든 상관 없습니다.

jq를 설치하는 방법

우리는 설치했다 jq 이 기사를 연구하는 데 사용한 모든 Linux 배포판에서.

설치하기 위해서 jq 우분투 에서이 명령을 입력하십시오 :

sudo apt-get install jq

터미널 창에서 "sudo apt-get install jq"명령

설치하기 위해서 jq Fedora에서 다음 명령을 입력하십시오.

sudo dnf install jq

터미널 창에서 "sudo dnf install jq"명령

설치하기 위해서 jq Manjaro에서 다음 명령을 입력하십시오.

sudo pacman -Sy jq

터미널 창에서 "sudo pacman -Sy jq"명령

JSON을 읽을 수있게 만드는 방법

JSON은 공백을 신경 쓰지 않으며 레이아웃은 영향을 미치지 않습니다. JSON 문법 규칙을 따르는 한 JSON을 처리하는 시스템이이를 읽고 이해할 수 있습니다. 이 때문에 JSON은 레이아웃을 고려하지 않고 단순하고 긴 문자열로 전송되는 경우가 많습니다. 탭, 공백 및 개행 문자를 JSON에 포함 할 필요가 없기 때문에 약간의 공간이 절약됩니다. 물론,이 모든 것의 단점은 인간이 그것을 읽으려고 할 때입니다.

NASA 사이트에서 국제 우주 정거장의 위치를 ​​알려주는 짧은 JSON 객체를 가져와 봅시다. 우리는 사용할 것이다 curl파일을 다운로드하여 JSON 객체를 검색 할 수 있습니다.

상태 메시지는 신경 쓰지 않습니다 curl 일반적으로 생성하므로 다음을 사용하여 다음을 입력합니다. -s (자동) 옵션 :

curl -s http://api.open-notify.org/iss-now.json

터미널 창에서 "curl -s http://api.open-notify.org/iss-now.json"명령

이제 약간의 노력으로 이것을 읽을 수 있습니다. 데이터 값을 선택해야하지만 쉽지 않거나 편리하지 않습니다. 이것을 반복하되 이번에는 파이프를 통해 jq.

jq 필터를 사용하여 JSON을 구문 분석하며이 필터 중 가장 간단한 것은 마침표 (.)는 “전체 개체를 인쇄합니다”를 의미합니다. 기본적으로, jq 출력을 예쁘게 인쇄합니다.

우리는 모두 함께 넣고 다음을 입력하십시오.

curl -s http://api.open-notify.org/iss-now.json | jq .

"curl -s http://api.open-notify.org/iss-now.json | jq." 터미널 창에서 명령.

훨씬 낫다! 이제 무슨 일인지 정확히 알 수 있습니다.

전체 객체는 중괄호로 묶습니다. 그것은 두 개의 키 : 이름 쌍을 포함합니다 : messagetimestamp. 또한 iss_position에는 두 개의 키 : 값 쌍이 포함됩니다. longitudelatitude.

다시 한번 시도하겠습니다. 이번에는 다음을 입력하고 출력을 “iss.json”이라는 파일로 리디렉션합니다.

curl -s http://api.open-notify.org/iss-now.json | jq . > iss.json
cat iss.json

터미널 창에서 "curl -s http://api.open-notify.org/iss-now.json | jq.> iss.json"및 "cat iss.json"명령

이를 통해 하드 드라이브에 JSON 객체의 복사본이 잘 정리되어 있습니다.

관련 : curl을 사용하여 Linux 명령 행에서 파일을 다운로드하는 방법

데이터 값에 액세스

위에서 보았 듯이 jq JSON에서 파이프되는 데이터 값을 추출 할 수 있습니다. 파일에 저장된 JSON을 사용할 수도 있습니다. 명령 줄이 복잡하지 않도록 로컬 파일로 작업 할 것입니다. curl 명령. 이렇게하면 따라하기가 더 쉬워집니다.

JSON 파일에서 데이터를 추출하는 가장 간단한 방법은 키 이름을 제공하여 데이터 값을 얻는 것입니다. 마침표와 키 이름을 공백없이 입력하십시오. 키 이름에서 필터를 만듭니다. 우리는 또한 말할 필요가있다 jq 사용할 JSON 파일

다음을 입력하여 message 값:

jq .message iss.json

터미널 창에서 "jq .message iss.json"명령

jq 의 텍스트를 인쇄 message 터미널 창의 값.

공백이나 문장 부호가 포함 된 키 이름이 있으면 필터를 따옴표로 묶어야합니다. 일반적으로 문자, 숫자 및 밑줄 만 사용하므로 JSON 키 이름에는 문제가 없습니다.

먼저 다음을 입력하여 timestamp 값:

jq .timestamp iss.json

터미널 창에서 "jq .timestamp iss.json"명령

타임 스탬프 값이 검색되어 터미널 창에서 인쇄됩니다.

그러나 어떻게 우리는 내부의 가치에 접근 할 수 있습니까? iss_position 목적? JSON 도트 표기법을 사용할 수 있습니다. 우리는 포함합니다 iss_position 키 값에 대한 “경로”의 객체 이름. 이를 위해 키 안에있는 오브젝트의 이름이 키 자체의 이름보다 우선합니다.

다음을 포함하여 다음을 입력합니다. latitude 키 이름 ( “.iss_position”과 “.latitude”사이에 공백이 없음) :

jq .iss_position.latitude iss.json

터미널 창에서 "jq .iss_position.latitude iss.json"명령

여러 값을 추출하려면 다음을 수행해야합니다.

  • 명령 행에 키 이름을 나열하십시오.
  • 쉼표로 구분하십시오 (,).
  • 따옴표로 묶습니다 (") 또는 아포스트로피 (').

이를 염두에두고 다음을 입력하십시오.

jq ".iss_position.latitude, .timestamp" iss.json

터미널 창에서 "jq".iss_position.latitude, .timestamp "iss.json"명령

이 두 값은 터미널 창에 인쇄됩니다.

배열 작업

NASA와 다른 JSON 객체를 가져옵니다.

이번에는 우주에있는 우주 비행사 목록을 사용하겠습니다.

curl -s http://api.open-notify.org/astros.json

터미널 창에서 "curl -s http://api.open-notify.org/astros.json"명령

알았어, 효과가 있었으니 다시 해보자

다음을 입력하여 연결합니다 jq “astro.json”이라는 파일로 리디렉션하십시오.

curl -s http://api.open-notify.org/astros.json | jq . > astro.json

터미널 창에서 "curl -s http://api.open-notify.org/astros.json | jq.> astros.json"명령. ' width = "646"height = "77"onload = "pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this);" onerror = "this.onerror = null; pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this);"></p>
<p>이제 파일을 확인하기 위해 다음을 입력하겠습니다.</p>
<pre>less astro.json</pre>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-532295 size-full" src="https://www.howtogeek.com/wp-content/uploads/2020/01/13-4.png" alt=

아래에서 볼 수 있듯이 우주에서 우주 비행사 목록과 우주선을 볼 수 있습니다.

터미널 창에서 "less astros.json"의 출력.

이 JSON 객체에는 people. 여는 브래킷으로 인해 배열임을 알고 있습니다 (() (위 스크린 샷에서 강조 표시됨). 각각 두 개의 키 : 값 쌍을 포함하는 객체의 배열입니다. namecraft.

이전과 마찬가지로 JSON 도트 표기법을 사용하여 값에 액세스 할 수 있습니다. 또한 괄호 (())를 배열 이름에 추가하십시오.

이 모든 것을 염두에두고 다음을 입력하십시오.

jq ".people().name" astro.json

터미널 창에서 "jq".people (). name "astros.json"명령

이번에는 모든 이름 값이 터미널 창에 인쇄됩니다. 우리가 요구 한 것 jq 할 일은 배열의 모든 객체에 대한 이름 값을 인쇄하는 것입니다. 꽤 깔끔 해요?

배열의 위치를 ​​대괄호로 묶으면 단일 객체의 이름을 검색 할 수 있습니다 (())를 명령 행에 배열은 제로 오프셋 인덱싱을 사용합니다. 즉, 배열의 첫 번째 위치에있는 객체가 0입니다.

배열의 마지막 객체에 액세스하려면 -1을 사용할 수 있습니다. 배열에서 마지막 두 번째 객체를 얻으려면 -2 등을 사용할 수 있습니다.

때로는 JSON 객체가 배열의 요소 수를 제공하는 경우도 있습니다. 배열과 함께 key : name 쌍이 포함되어 있습니다. number 6의 값으로.

이 배열에는 다음과 같은 수의 객체가 있습니다.

jq ".people(1).name" astro.json
jq ".people(3).name" astro.json
jq ".people(-1).name" astro.json
jq ".people(-2).name" astro.json

"jq".people (1) .name "astro.json," "jq".people (3) .name "astro.json," "jq".people (-1) .name "astro.json," 및 터미널 창에서 "jq".people (-2) .name "astro.json".

배열 내에서 시작 및 종료 객체를 제공 할 수도 있습니다. 이것을 “슬라이스”라고하며 약간 혼란 스러울 수 있습니다. 어레이는 0 오프셋을 사용합니다.

인덱스 위치 2에서 개체를 인덱스 위치 4까지 검색하려면 (포함하지는 않음) 다음 명령을 입력하십시오.

jq ".people(2:4)" astro.json

터미널 창에서 "jq".people (2 : 4) "astro.json"명령

그러면 배열 인덱스 2 (어레이의 세 번째 오브젝트)와 3 (어레이의 네 번째 오브젝트)에 오브젝트가 인쇄됩니다. 배열의 다섯 번째 개체 인 배열 인덱스 4에서 처리를 중지합니다.

이를 더 잘 이해하는 방법은 명령 행을 실험하는 것입니다. 작동 방식을 곧 확인할 수 있습니다.

필터와 함께 파이프를 사용하는 방법

한 필터에서 다른 필터로 출력을 파이프 할 수 있으며 새로운 심볼을 배울 필요가 없습니다. Linux 명령 행과 동일 jq 세로 막대 (|)는 파이프를 나타냅니다.

우리는 말할 것이다 jq 파이프 people 에 배열 .name 터미널 창에 우주 비행사의 이름을 나열 해야하는 필터.

우리는 다음을 입력합니다 :

jq ".people() | .name" astro.json

"jq".people () | 터미널 창에서 .name "astros.json"명령

관련 : Linux에서 파이프를 사용하는 방법

배열 만들기 및 결과 수정

사용할 수있다 jq 배열과 같은 새로운 객체를 생성합니다. 이 예에서는 세 개의 값을 추출하고 해당 값을 포함하는 새 배열을 만듭니다. 오프닝 (() 및 닫는 괄호 ())은 필터 문자열의 첫 번째 및 마지막 문자입니다.

우리는 다음을 입력합니다 :

jq "(.iss-position.latitude, iss_position.longitude, .timestamp)" iss.json

터미널 창에서 "jq"(.iss-position.latitude, iss_position.longitude, .timestamp) "iss.json"명령

출력은 대괄호로 묶고 쉼표로 구분되어 올바르게 구성된 배열이됩니다.

검색 할 때 숫자 값을 조작 할 수도 있습니다. 당 기자 timestamp ISS 위치 파일에서 다시 추출한 다음 반환되는 값을 변경하십시오.

이렇게하려면 다음을 입력하십시오.

jq ".timestamp" iss.json
jq ".timestamp - 1570000000" iss.json

터미널 창에서 "jq".timestamp "iss.json"및 "jq".timestamp-1570000000 "iss.json"명령

이는 값 배열에서 표준 오프셋을 추가하거나 제거해야하는 경우에 유용합니다.

다음을 입력하여 iss.json 파일은 다음을 포함합니다 :

jq . iss.json

터미널 창에서 "jq. iss.json"명령

우리가 제거하고 싶다고 가정 해 봅시다. message 키 : 값 쌍. 국제 우주 정거장의 위치와는 아무런 관련이 없습니다. 위치가 성공적으로 검색되었음을 나타내는 플래그 일뿐입니다. 요구 사항을 초과하는 경우이를 제거 할 수 있습니다. (당신은 그것을 무시할 수도 있습니다.)

사용할 수있다 jq삭제 기능, del()키 : 값 쌍을 삭제합니다. 메시지 키 : 값 쌍을 삭제하려면 다음 명령을 입력하십시오.

jq "del(.message)" iss.json

터미널 창에서 "jq"del (.message) "iss.json"명령

실제로 “iss.json”파일에서 삭제되지는 않습니다. 명령 출력에서 ​​제거합니다. 없이 파일을 새로 만들어야하는 경우 message 키 : 값 쌍을 입력하고 명령을 실행 한 다음 출력을 새 파일로 리디렉션하십시오.

더 복잡한 JSON 객체

더 많은 NASA 데이터를 검색하겠습니다. 이번에는 전 세계 유성 영향 사이트에 대한 정보가 포함 된 JSON 객체를 사용합니다. 이것은 이전에 다루었던 것보다 훨씬 복잡한 JSON 구조를 가진 더 큰 파일입니다.

먼저 다음을 입력하여 “strikes.json”이라는 파일로 리디렉션합니다.

curl -s https://data.nasa.gov/resource/y77d-th95.json | jq . > strikes.json

터미널 창에서 "curl -s https://data.nasa.gov/resource/y77d-th95.json | jq.> strikes.json"명령. ' width = "646"height = "77"onload = "pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this);" onerror = "this.onerror = null; pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this);"></p>
<p>JSON의 모양을 보려면 다음을 입력하십시오.</p>
<pre>less strikes.json</pre>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-532551 size-full" src="https://www.howtogeek.com/wp-content/uploads/2020/01/23-4.png" alt=

아래와 같이 파일은 여는 괄호 (()이므로 전체 객체는 배열입니다. 배열의 객체는 키 : 값 쌍의 모음이며라는 중첩 된 객체가 있습니다. geolocation. 그만큼 geolocation 객체에는 추가 키 : 값 쌍과 coordinates.

"less strikes.json"명령의 출력은 터미널 창에서 적습니다.

배열 끝까지 인덱스 위치 995의 물체에서 유성 타격의 이름을 검색해 봅시다.

다음을 입력하여 세 가지 필터를 통해 JSON을 파이프합니다.

jq ".(995:) | .() | .name" strikes.json

"jq". (995 :) | . () | 터미널 창에서 .name "strikes.json"명령

필터는 다음과 같은 방식으로 작동합니다.

  • .(995:): 이것은 알려줍니다 jq 배열 인덱스 995에서 배열 끝까지 객체를 처리합니다. 콜론 뒤에 숫자가 없습니다 ( : )는 말한다 jq 배열의 끝까지 계속합니다.
  • .():이 배열 반복자는 알려줍니다 jq 배열의 각 객체를 처리합니다.
  • .name:이 필터는 이름 값을 추출합니다.

약간만 변경하면 배열에서 마지막 10 개의 객체를 추출 할 수 있습니다. “-10”은 지시합니다 jq 어레이의 끝으로부터 객체 (10)를 다시 처리하기 시작한다.

우리는 다음을 입력합니다 :

jq ".(-10:) | .() | .name" strikes.json

"jq". (-10 :) | . () | 터미널 창에서 .name "strikes.json"명령

이전 예제에서와 마찬가지로 다음을 입력하여 단일 객체를 선택할 수 있습니다.

jq ".(650).name" strikes.json

터미널 창에서 "jq". (650) .name "strikes.json"명령

문자열에 슬라이싱을 적용 할 수도 있습니다. 이를 위해 배열 인덱스 234에서 객체 이름의 처음 네 문자를 요청하려면 다음을 입력합니다.

jq ".(234).name(0:4)" strikes.json

터미널 창에서 "jq". (234) .name (0 : 4) "strikes.json"명령

특정 객체 전체를 볼 수도 있습니다. 이를 위해 다음을 입력하고 키 : 값 필터없이 배열 색인을 포함시킵니다.

jq ".(234)" strikes.json

터미널 창에서 "jq". (234) "strikes.json"명령

값만 보려면 키 이름없이 동일한 작업을 수행 할 수 있습니다.

이 예에서는 다음 명령을 입력합니다.

jq ".(234)()" strikes.json

터미널 창에서 "jq"(234) () "strikes.json"명령

각 객체에서 여러 값을 검색하려면 다음 명령에서 쉼표로 구분합니다.

jq ".(450:455) | .() | .name, .mass" strikes.json

"jq". (450 : 455) | . () | 터미널 창에서 .name, .mass "strikes.json"명령

중첩 된 값을 검색하려면 “경로”를 형성하는 개체를 식별해야합니다.

예를 들어 coordinates 모든 포괄적 인 배열을 포함해야합니다. geolocation 중첩 된 개체 및 중첩 된 개체 coordinates 아래와 같이 배열.

터미널 창에서 강조 표시된 중첩 JSON 객체의 배열 경로입니다.

보고 coordinates 배열의 인덱스 위치 121에있는 객체의 값을 입력하려면 다음 명령을 입력하십시오.

jq ".(121).geolocation.coordinates()" strikes.json

터미널 창에서 "jq". (121) .geolocation.coordinates () "strikes.json"명령

길이 기능

그만큼 jq length 함수는 적용되는 내용에 따라 다음과 같은 다른 메트릭을 제공합니다.

  • : 문자열의 길이 (바이트).
  • 사물: 객체의 키 : 값 쌍 수입니다.
  • 배열: 배열의 배열 요소 수입니다.

다음 명령은 name 인덱스 위치 100에서 시작하여 JSON 배열의 10 개 오브젝트 값 :

jq ".(100:110) | .().name | length" strikes.json

"jq". (100 : 110) | . (). name | 터미널 창에서 length "strikes.json"명령

배열의 첫 번째 객체에 몇 개의 키 : 값 쌍이 있는지 보려면 다음 명령을 입력하십시오.

jq ".(0) | length" strikes.json

"jq". (0) | 터미널 창에서 length "strikes.json"명령

키 기능

키 기능을 사용하여 작업해야하는 JSON에 대해 알아볼 수 있습니다. 키의 이름과 배열에 몇 개의 객체가 있는지 알려줍니다.

에서 키를 찾으려면 people “astro.json”파일의 object에 다음 명령을 입력하십시오.

jq ".people.(0) | keys" astro.json

"jq".people. (0) | 터미널 창에서 "astro.json"키를 누릅니다.

에 몇 개의 요소가 있는지 보려면 people 배열에 다음 명령을 입력하십시오.

jq ".people | keys" astro.json

"jq".people | 터미널 창에서 "astro.json"키를 누릅니다.

이것은 0에서 5까지 번호가 매겨진 6 개의 제로 오프셋 배열 요소가 있음을 나타냅니다.

has () 함수

당신은 사용할 수 있습니다 has() JSON을 조사하고 객체에 특정 키 이름이 있는지 확인하는 기능입니다. 키 이름은 따옴표로 묶어야합니다. 필터 명령을 작은 따옴표로 묶습니다 ('), 다음과 같이 :

jq '.() | has("nametype")' strikes.json

그만큼

아래 그림과 같이 배열의 각 개체가 검사됩니다.

터미널 창에서

특정 객체를 확인하려면 다음과 같이 배열 필터에 해당 색인 위치를 포함시킵니다.

jq '.(678) | has("nametype")' strikes.json

그만큼

그것없이 JSON 근처에 가지 마십시오

그만큼 jq 유틸리티는 Linux 세계에 사는 것이 즐거움을주는 전문적이고 강력하며 빠른 소프트웨어의 완벽한 예입니다.

이것은이 명령의 일반적인 기능에 대한 간단한 소개 일뿐입니다. 더 깊이 파고 싶다면 포괄적 인 jq 매뉴얼을 확인하십시오.