我有这个数据库查询:
select hostname,size from tableinfo
输出是这样的:
hostname size
------------------------- -----------
host1 28
host2 13
host3 79
host4 28
host5 17
或者,我可以这样做:
host1 28
host2 13
host3 79
host4 28
host5 17
我想编写一个 shell 脚本来将此输出转换为 JSON,但我真的不知道从哪里开始或做什么。 JSON 必须是这样的:
{
"data":[
{ "{#HOSTNAME}":"host1", "{#SIZE}":"28" } ,
{ "{#HOSTNAME}":"host2", "{#SIZE}":"13" } ,
{ "{#HOSTNAME}":"host3", "{#SIZE}":"79" } ,
{ "{#HOSTNAME}":"host4", "{#SIZE}":"28" } ,
{ "{#HOSTNAME}":"host5", "{#SIZE}":"17" }
]
}
答案1
jq
解决方案:
<your sql output> | jq -Rs '{"data": [split("\n") | map(select(length > 0))[]
| split(" +";"g")
| {"{#HOSTNAME}": .[0], "{#SIZE}": .[1]}]}'
输出:
{
"data": [
{
"{#HOSTNAME}": "host1",
"{#SIZE}": "28"
},
{
"{#HOSTNAME}": "host2",
"{#SIZE}": "13"
},
{
"{#HOSTNAME}": "host3",
"{#SIZE}": "79"
},
{
"{#HOSTNAME}": "host4",
"{#SIZE}": "28"
},
{
"{#HOSTNAME}": "host5",
"{#SIZE}": "17"
}
]
}
答案2
假设这是一个 SQLite3 数据库(其他数据库引擎将有自己的本机方式来生成 JSON 输出):
sqlite3 database.db \
'.mode json' \
'SELECT hostname AS `{#HOSTNAME}`, size AS `{#SIZE}` FROM tableinfo' |
jq '{ data: . }'
这会从数据库中以数组的形式获取 JSON 格式的数据,然后将jq
其插入到data
对象的键下。 SELECT 查询根据需要更改用于主机名和大小的键的名称。
这将为您提供一个与您要求的内容等效的 JSON 文档:
{
"data": [
{
"{#HOSTNAME}": "host1",
"{#SIZE}": "28"
},
{
"{#HOSTNAME}": "host2",
"{#SIZE}": "13"
},
{
"{#HOSTNAME}": "host3",
"{#SIZE}": "79"
},
{
"{#HOSTNAME}": "host4",
"{#SIZE}": "28"
},
{
"{#HOSTNAME}": "host5",
"{#SIZE}": "17"
}
]
}
如果你想要精确的您提到的输出的格式,然后将jq
上面管道中的命令替换为以下内容jtc
命令:
jtc -T '{"data": {{}} }' -tc
这会将读取的数据插入到sqlite3
模板中,作为键的值data
,并且-tc
会jtc
产生其“半紧凑”的漂亮打印输出格式,它看起来像这样:
{
"data": [
{ "{#HOSTNAME}": "host1", "{#SIZE}": "28" },
{ "{#HOSTNAME}": "host2", "{#SIZE}": "13" },
{ "{#HOSTNAME}": "host3", "{#SIZE}": "79" },
{ "{#HOSTNAME}": "host4", "{#SIZE}": "28" },
{ "{#HOSTNAME}": "host5", "{#SIZE}": "17" }
]
}
从表格数据(两个简单的列)中,您可以使用米勒 ( mlr
)创建初始数组,然后使用相同的jq
或jtc
命令将其全部插入到该data
键下:
$ mlr --n2j -S label '{#HOSTNAME},{#SIZE}' file | jtc -T '{ "data": {{}} }' -tc
{
"data": [
{ "{#HOSTNAME}": "host1", "{#SIZE}": "28" },
{ "{#HOSTNAME}": "host2", "{#SIZE}": "13" },
{ "{#HOSTNAME}": "host3", "{#SIZE}": "79" },
{ "{#HOSTNAME}": "host4", "{#SIZE}": "28" },
{ "{#HOSTNAME}": "host5", "{#SIZE}": "17" }
]
}
我使用and 的--n2j
简写(“读取工具箱索引格式化数据,写入 JSON”),并添加了内容以阻止 Miller 推断大小数据应该是整数(而不是将其视为字符串)。--inidx
--ojson
-S