jq를 사용하여 JSON 데이터를 구문 분석하고 csv로 변환

jq를 사용하여 JSON 데이터를 구문 분석하고 csv로 변환

api json 데이터를 다운로드하여 csv 파일 형태로 최종 결과로 변환하고 있습니다.

샘플 데이터 형식은 다음과 같습니다.

{
    "content": [{
            "Title": "abc",
            "brand": "xyz",
            "information": {
                "c1": "101",
                "c2": "11111",
                "c3": "a,b,c,d,e:abc."
            }
        },
        {
            "Title": "RX100",
            "brand": "Yamaha",
            "information": {
                "c1": "102",
                "c2": "22222",
                "c3": "a."
            }
        },
        {
            "Title": "victor",
            "brand": "TVS",
            "information": {
                "c1": "103",
                "c2": "33333",
                "c3": "a,b,c"
            }
        },
        {
            "Title": "R15",
            "brand": "Yamaha",
            "information": {
                "c1": "104",
                "c2": "44444",
                "c3": "a,b"
            }
        }
    ]
}

헤더 수에 따라 여러 csv로 성공적으로 다운로드하고 변환했습니다. 여러 csv 파일로 변환한 후 데이터는 다음과 같습니다.

Headers-> c1,c2,c3
csv1-->   101,11111,a,b,c,d,e:abc.
csv2-->   102,22222,a.
csv3-->   103,33333,a,b,c.
csv4-->   104,44444,a,b.

하지만 위의 데이터를 다음 형식으로 원합니다.

Headers-> c1,c2,c3,c4,c5,c6,c7
csv1-->   101,11111,a,b,c,d,e:abc.
csv2-->   102,22222,a.
csv3-->   103,33333,a,b,c.
csv4-->   104,44444,a,b.

json.json을 사용하여 내 json 파일에 있는 ","를 기반으로 c3을 다른 수의 열로 나눌 수 있습니까? c3 열은 존재하는 요소 수에 따라 나누어지며 c3 데이터의 최대값이 됩니다.

답변1

이 정확한 데이터를 위해서는

jq -r '.content[].information | [.c1, .c2, .c3] | join(",")' < sample.json

작동합니다. 연결된 CSV 파일의 효과를 복제하려면 세 열 사이에 쉼표를 삽입하기만 하면 됩니다. 보다 복잡한 실제 데이터, 특히 숫자의 경우 다음이 더 좋습니다.

jq -r '.content[].information | [.c1, .c2, (.c3|split(",")|.[])] | @csv' < sample.json

그것은 모두 꽤 표준 .c3|split(",")|.[]적입니다.

  1. 3열의 값을 추출합니다.
  2. 값을 쉼표 배열로 분할
  3. 배열을 평면화

@csv그런 다음 배열을 CSV 형식으로 변환합니다. 그러면 예제 파일에 대해 다음과 같은 출력이 생성됩니다.

"101","11111","a","b","c","d","e:abc."
"102","22222","a."
"103","33333","a","b","c"
"104","44444","a","b"

따옴표가 필요하지 않은 경우 가장 안정적인 방법은 @tsv탭을 사용하고 바꾸는 것입니다.

jq -r '.content[].information|[.c1, .c2, .c3|split(",")|.[]] | @tsv|gsub("\t"; ",")' < sample.json

모든 값이 문자열인 경우 에도 join(",")이를 다시 사용할 수 있습니다.


텍스트 헤더 행도 생성하려면 다음과 c1,...c7같이 하세요.

jq -r '[.content[].information|[.c1, .c2, (.c3|split(",")|.[])]] | (([range([.[] | length] | max)|"c" + (.+1|tostring)]|join(",")), (.[] | join(",")))' < sample.json

세 부분으로 구성됩니다. 첫 번째 부분은 이전과 같이 열 배열을 생성하고 나머지 두 부분은 이를 입력으로 사용합니다.

  1. ([range([.[] | length] | max)|"c" + (.+1|tostring)]|join(","))헤더 행 생성: 행 길이 배열을 생성하고 0..maximum 범위를 생성하고 이를 매핑하여 "c1".."c7" 배열을 생성한 다음 모두 쉼표로 연결하여 행의 최대 길이를 찾습니다. .
  2. (.[] | join(","))이전 후반전과 마찬가지로 동일하게 @csv적용됩니다.

관련 정보