从 SQL 查询输出生成 JSON

从 SQL 查询输出生成 JSON

我有这个数据库查询:

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,并且-tcjtc产生其“半紧凑”的漂亮打印输出格式,它看起来像这样:

{
   "data": [
      { "{#HOSTNAME}": "host1", "{#SIZE}": "28" },
      { "{#HOSTNAME}": "host2", "{#SIZE}": "13" },
      { "{#HOSTNAME}": "host3", "{#SIZE}": "79" },
      { "{#HOSTNAME}": "host4", "{#SIZE}": "28" },
      { "{#HOSTNAME}": "host5", "{#SIZE}": "17" }
   ]
}

从表格数据(两个简单的列)中,您可以使用米勒 ( mlr)创建初始数组,然后使用相同的jqjtc命令将其全部插入到该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

相关内容