在unix中使用jq将表记录转换为JSON文件

use*_*643 2 shell-script text-processing json

我在 Linux 机器上有一个表,其中有许多记录;我正在运行一个查询来获取:

select * from TABNAME_XYZ


CID CN    XY     NAT   UIC    DATE        Region
12  2123  120.9  29.0  100.0  2018-06-08  JAIPUR
13  0987  78.9   100.3 28.8   2020-12-09  DELHI
Run Code Online (Sandbox Code Playgroud)

我想编写一个 shell 脚本,将其输出转换为 JSON,但我真的不知道从哪里开始或做什么。JSON 必须是这样的:

{"CID":"12","CN":"2123","DATA":{"XY":120.9,"NAT":29.0,"UIC":100.0,"Date":"2018-06-08","REGION":"JAIPUR"}},
{"CID":"13","CN":"0987","DATA":{"XY":78.9,"NAT":100.3,"UIC":28.8,"Date":"2020-12-09","REGION":"DELHI"}}
Run Code Online (Sandbox Code Playgroud)

jq我的系统上已经有了。

Kus*_*nda 5

假设字段始终按照给定的顺序,输入的第一行有一个标题行,并且多个空格字符分隔字段,您可以使用 压缩连续空格并使用tr解析数据jq

database-client-command |
tr -s ' ' |
jq -c -Rn '
        input  | split(" ") as $head |
        inputs | split(" ") |
                to_entries |
                        map(.key = $head[.key]) |
                        [ .[:2][], { key: "DATA", value: (.[2:] | from_entries) } ] |
                from_entries'

Run Code Online (Sandbox Code Playgroud)

jq表达式从单独的行中读取原始数据tr

第一行被分成标题并存储到 中的数组中$head

我们将剩余的行分成数组,就像处理标题一样。过滤器将每个数组转换为“条目形式”(带有和键to_entries的对象的集合),并用作为键的标头替换数字数组索引。keyvaluemap()$head

之后map(),过滤器重新排列数组,将第三个元素向下移动到单独的DATA子对象中,并从“条目形式”转换回来。

当完成键和数据重新排列后,from_entries过滤器从“输入表单”返回数组。

脚本的输出将是一组 JSON 对象,并且考虑到问题中的数据,这些对象将如下所示。

{"CID":"12","CN":"2123","DATA":{"XY":"120.9","NAT":"29.0","UIC":"100.0","DATE":"2018-06-08","Region":"JAIPUR"}}
{"CID":"13","CN":"0987","DATA":{"XY":"78.9","NAT":"100.3","UIC":"28.8","DATE":"2020-12-09","Region":"DELHI"}}
Run Code Online (Sandbox Code Playgroud)

如果您想更改RegionREGIONDATEinto Date,请考虑在查询数据库时执行此操作或作为后处理步骤。

请注意,由于第一行尾随逗号,您的预期结果不是有效的 JSON。