将 SQLite CSV 输出转换为 JSON

将 SQLite CSV 输出转换为 JSON

我想从命令行将 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命名字段keyfield2重命名字段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需要一个“条目”数组,即带有keyvalue键的对象。

允许 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 中处于活动状态,您仍然可以使用相同的技巧来重命名字段keyvalue通过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每个输入记录中的字段值。然后删除两个首字母keyvalue字段,并将输出创建为具有单个 JSON 对象的数组。

相关内容