我想从命令行将 SQLite 输出格式化为 JSON 格式。目前,我的 CSV 输出如下所示:
label1,value1
label2,value2
label3,value3
...
现在我想将其格式化为这样:
{'label1' : 'value1', 'label2': 'value2', ... }
谢谢!
答案1
我用 GNU 测试了这个awk
......sed
不确定其他版本是否也如此。
awk -F, '{printf "'\''%s'\'' : '\''%s'\'', ", $1, $2} END {print "}" }' input.csv | sed -e 's/^/{/' -e 's/, }/}/' > output.json
答案2
有效的 JSON 使用双引号,因此:
awk -F, 'BEGIN{print "{"} {if (notfirst) {print ","}; print "\"" $1 "\":\"" $2 "\""; notfirst=1} END {print "\"\":\"\"}" }' input.csv
不使用 sed 也更简单
答案3
假设我们有这个:
sqlite> .mode box
sqlite> SELECT * FROM mytable;
┌────────┬────────┐
│ field1 │ field2 │
├────────┼────────┤
│ label1 │ value1 │
│ label2 │ value2 │
│ label3 │ value3 │
└────────┴────────┘
...我们可以将数据提取为 JSON,并重field1
命名字段key
和field2
重命名字段value
:
$ sqlite3 mydatabase.db '.mode json' 'SELECT field1 AS key, field2 AS value FROM mytable'
[{"key":"label1","value":"value1"},
{"key":"label2","value":"value2"},
{"key":"label3","value":"value3"}]
这可以直接通过 的jq
过滤from_entries
器来创建您需要的输出:
$ sqlite3 mydatabase.db '.mode json' 'SELECT field1 AS key, field2 AS value FROM mytable' | jq from_entries
{
"label1": "value1",
"label2": "value2",
"label3": "value3"
}
注意过滤from_entries
器在jq
需要一个“条目”数组,即带有key
和value
键的对象。
允许 SQLite 输出 JSON,然后处理该 JSON,以jq
确保正确处理包含引号、换行符和其他可能有问题的字符的数据:
sqlite> SELECT * FROM mytable;
┌─────────────────────┬────────────┐
│ field1 │ field2 │
├─────────────────────┼────────────┤
│ label1 │ value1 │
├─────────────────────┼────────────┤
│ label2 │ value2 │
├─────────────────────┼────────────┤
│ label3 │ value3 │
├─────────────────────┼────────────┤
│ label "with quotes" │ value with │
│ │ newline │
└─────────────────────┴────────────┘
$ sqlite3 mydatabase.db '.mode json' 'SELECT field1 AS key, field2 AS value FROM mytable' | jq from_entries
{
"label1": "value1",
"label2": "value2",
"label3": "value3",
"label \"with quotes\"": "value with\nnewline"
}
如果您有一个由 SELECT 查询创建的预先存在的 CSV 文件,同时.mode csv
在 SQLite 中处于活动状态,您仍然可以使用相同的技巧来重命名字段key
并value
通过from_entries
首先jq
使用 Miller 重新标记字段并从 CSV 转换为JSON:
$ mlr --c2j label key,value mydata.csv | jq from_entries
{
"label2": "value2",
"label3": "value3",
"label \"with quotes\"": "value with\nnewline"
}
如果您已删除标题行,则可以mlr
选择-N
表示无标题 CSV 输入。
显然,如果您已经在使用 Miller,您可以让它完成所有工作,而无需涉及jq
:
$ mlr --c2j label key,value then put -q 'end { emit @record } @record[$key] = $value' then cut -x -f key,value mydata.csv
[
{
"label2": "value2",
"label3": "value3",
"label \"with quotes\"": "value with\nnewline"
}
]
这将从 中读取数据mydata.csv
,重新标记两个字段,然后收集新记录中的所有数据,该记录的字段取决于key
每个输入记录中的字段值。然后删除两个首字母key
和value
字段,并将输出创建为具有单个 JSON 对象的数组。