使用jq将JSON转换为CSV

3
我将尝试使用jq从JSON文件中提取sids、ll、state、name和smry值,并将其导出为csv文件。请参考以下内容: JSON文件(out.json):
{
    "data": [
        {
            "meta": {
                "uid": 74529,
                "ll": [
                    -66.9333,
                    47.0667
                ],
                "sids": [
                    "CA008102500 6"
                ],
                "state": "NB",
                "elev": 1250,
                "name": "LONG LAKE"
            },
            "smry": [
                [
                    "42",
                    "1955-02-23"
                ]
            ]
        },
        {
            "meta": {
                "uid": 74534,
                "ll": [
                    -67.2333,
                    45.9667
                ],
                "sids": [
                    "CA008103425 6"
                ],
                "state": "NB",
                "elev": 150.9,
                "name": "NACKAWIC"
            },
            "smry": [
                [
                    "40",
                    "1969-02-23"
                ]
            ]
        },
        {
            "meta": {
                "uid": 74549,
                "ll": [
                    -67.4667,
                    47.4667
                ],
                "sids": [
                    "CA008104933 6"
                ],
                "state": "NB",
                "elev": 794,
                "name": "ST QUENTIN"
            },
            "smry": [
                [
                    "M",
                    "M"
                ]
            ]
        },
        {
            "meta": {
                "uid": 74550,
                "ll": [
                    -67.2667,
                    45.1833
                ],
                "sids": [
                    "CA008104936 6"
                ],
                "state": "NB",
                "elev": 36.1,
                "name": "ST STEPHEN"
            },
            "smry": [
                [
                    "48",
                    "1900-02-23"
                ]
            ]
        },
        {
            "meta": {
                "uid": 74554,
                "ll": [
                    -67.25,
                    47.2667
                ],
                "sids": [
                    "CA008105000 6"
                ],
                "state": "NB",
                "elev": 915.4,
                "name": "SISSON DAM"
            },
            "smry": [
                [
                    "35",
                    "1955-02-23"
                ]
            ]
        }
    ]
}

终端代码:

jq '.data | [ {sids, ll, state, name, smry} ]' out.json

我遇到了以下错误:
assertion "cb == jq_util_input_next_input_cb" failed: file "/usr/src/ports/jq/jq-1.5-3.x86_64/src/jq-1.5/util.c", line 371, function: jq_util_input_get_position
Aborted (core dumped)

期望输出示例:

sids, ll, state, name, smry
CA008102500, -66.9333, 47.0667, NB, LONG LAKE, 42,1955-02-23
CA008103425, -67.2333, 45.9667, NB, NACKAWIC, 35,1955-02-23

我做错了什么?


你的尝试忽略了JSON中的许多结构。不过,你可能正在使用旧版本的jq;我得到了一个简单的错误jq: error (at tmp.json:6): Cannot index array with string "sids"而不是核心转储。 - chepner
嗨@chepner!我对json不是很熟悉,但我已经认识到文件的复杂树形结构。 - arnpry
@arnpry:以下是一些入门内容,jq --raw-output '.data[] | .meta | "\(.sids) \(.ll) \(.state) \(.name)"',可以得到值,但我不太了解如何展开数组。 - Inian
如果任何程序转储其核心并且您能够重现它,则该程序正在做错事,而不是您。您应该向上游报告错误。 - rindeal
@rindeal 在 jq 1.5 中不会发生核心转储;如果存在错误,那么已经被修复了。 - chepner
1个回答

6

这个问题稍微有点复杂,因为你需要先扁平化 sidsllsmry,然后再扁平化整个记录。我建议创建一个 jq 文件:

foo.jq

.data[]|{
    "sids":(.meta.sids[0]|split(" ")[0]),
    "ll":(.meta.ll|map(tostring)|join(",")),
    "state":.meta.state,
    "name":.meta.name,
    "smry":(.smry[]|join(","))
}|join(",")
# or, for robust csv output
# } | @csv 

然后调用:

jq -rf foo.jq file.json

输出:

CA008102500,-66.9333,47.0667,NB,LONG LAKE,42,1955-02-23
CA008103425,-67.2333,45.9667,NB,NACKAWIC,40,1969-02-23
CA008104933,-67.4667,47.4667,NB,ST QUENTIN,M,M
CA008104936,-67.2667,45.1833,NB,ST STEPHEN,48,1900-02-23
CA008105000,-67.25,47.2667,NB,SISSON DAM,35,1955-02-23

这看起来像是我正在尝试做的事情!不过出现了以下错误:"jq: error: syntax error, unexpected INVALID_CHARACTER (Unix shell quoting issues?) at <top-level>, line 1: jq: 1 compile error" - arnpry
你真的不敢相信吗?你确定已经正确地复制了命令吗? - hek2mgl
1
糟糕!我使用Notepad ++创建了文件,当我保存文件时,EOL转换设置为Windows(它会添加额外的换行符),而不是Unix。 - arnpry
使用 join(",") 处理边角情况不如使用 @csv - Charles Duffy
@CharlesDuffy 确实。但是在我看来,join(",") 对于非边缘情况很好,因为你可以轻松地将其管道传输到 awk -F,。但是,在一个健壮的脚本中,我会使用 @csv - hek2mgl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接