我想将我的sqlite数据从我的数据库转换为JSON格式。
我想使用这种语法:
sqlite3 -line members.db“SELECT * FROM members LIMIT 3”> members.txt
输出:
id = 1
fname = Leif
gname = Håkansson
genderid = 1
id = 2
fname = Yvonne
gname = Bergman
genderid = 2
id = 3
fname = Roger
gname = Sjöberg
genderid = 1
如何在for循环中使用nice和structur代码执行此操作? (仅限Bash)
我尝试了一些awk和grep,但还没有取得很大的成功。
一些提示会很好。
我想要一个与此类似的结果:
[
{
"id":1,
"fname":"Leif",
"gname":"Hakansson",
"genderid":1
},
{
"id":2,
"fname":"Yvonne",
"gname":"Bergman",
"genderid":2
},
{
"id":3,
"fname":"Roger",
"gname":"Sjberg",
"genderid":1
}
}
答案 0 :(得分:8)
如果您的sqlite3是使用json1扩展编译的(或者如果您可以获得带有json1扩展名的sqlite3版本),那么您可以使用它来生成JSON对象(每行一个JSON对象)。例如:
$(".buttons").click(function() {
var div = $("<div/>");
var offset = $(this).offset();
var posx = event.pageX - offset.left;
var posy = event.pageY - offset.top;
div.addClass("ripple");
div.css({
"width": $(this).width,
"height": $(this).height,
"top": posy,
"left": posx,
"background": $(this).data("ripple_color"),
}).appendTo($(this));
setTimeout(function() {
div.remove();
}, 1500);
});
然后,您可以使用jq之类的工具将对象流转换为对象数组,例如将sqlite3的输出传递给select json_object('id', id, 'fname', fname, 'gname', gname, 'genderid', genderid) ...
。
(一个不太烦人的替代方案可能是使用sqlite3函数json_array(),它生成一个数组,你可以使用jq将其重组为一个对象。)
如果json1扩展名不可用,那么您可以使用以下内容作为起点:
jq -s .
或者,您可以使用以下jq脚本,该脚本将RHS上出现的数字字符串“=”转换为数字:
awk 'BEGIN { print "["; }
function out() {if (n++) {print ","}; if (line) {print "{" line "}"}; line="";}
function trim(x) { sub(/^ */, "", x); sub(/ *$/, "", x); return x; }
NF==0 { out(); next};
{if (line) {line = line ", " }
i=index($0,"=");
line = line "\"" trim(substr($0,1,i-1)) ": \"" substr($0, i+2) "\""}
END {out(); print "]"} '
答案 1 :(得分:2)
我认为我更倾向于使用每条记录一行来解析sqlite输出,而不是使用sqlite3 -line
建议的非常冗长的输出格式。所以,我会这样做:
sqlite3 members.db "SELECT * FROM members LIMIT 3"
这让我解析:
1|Leif|Hakansson|1
2|Yvonne|Bergman|2
3|Roger|Sjoberg|1
如果我使用
将输入分隔符设置为awk
,我现在可以使用|
解析该问题
awk -F '|'
并使用以下内容拾取每行上的4个字段,并将它们保存在如下数组中:
{ id[++i]=$1; fname[i]=$2; gname[i]=$3; genderid[i]=$4 }
然后我需要做的就是打印最后需要的输出格式。但是,你的输出中有双引号,在awk
引用它们很难,所以我暂时使用另一个管道符号(|
)作为双引号然后,最后,我得到tr
用双引号替换所有管道符号 - 只是为了使代码更容易。所以整个解决方案看起来像这样:
sqlite3 members.db "SELECT * FROM members LIMIT 3" | awk -F'|' '
# sqlite output line - pick up fields and store in arrays
{ id[++i]=$1; fname[i]=$2; gname[i]=$3; genderid[i]=$4 }
END {
printf "[\n";
for(j=1;j<=i;j++){
printf " {\n"
printf " |id|:%d,\n",id[j]
printf " |fname|:|%s|,\n",fname[j]
printf " |gname|:|%s|,\n",gname[j]
printf " |genderid|:%d\n",genderid[j]
closing=" },\n"
if(j==i){closing=" }\n"}
printf closing;
}
printf "]\n";
}' | tr '|' '"'
答案 2 :(得分:1)
只需在 SQLite 3.33.0 或更高版本中输入 -json
参数并获得 json 输出:
$ sqlite3 -json database.db "select * from TABLE_NAME"
来自 SQLite Release 3.33.0 注意:
<块引用>...
...
答案 3 :(得分:0)
总比不插入jo迟。
将sqlite3保存到文本文件。
获取jo(jo也在发行版存储库中可用)
并使用此bash脚本。
while read line
do
id=`echo $line | cut -d"|" -f1`
fname=`echo $line | cut -d"|" -f2`
gname=`echo $line | cut -d"|" -f3`
genderid=`echo $line | cut -d"|" -f4`
jsonline=`jo id="$id" fname="$fname" gname="$gname" genderid="$genderid"`
json="$json $jsonline"
done < "$1"
jo -a $json
答案 4 :(得分:0)
Sqlite-utils 完全符合您的要求。默认情况下,输出将为 JSON。
答案 5 :(得分:-1)
请不要使用awk
创建(或解析)json。为此有专用工具。 xidel
之类的工具。
首先,最重要的是html,xml和json解析器,xidel
也可以解析纯文本。
我想使用此工具提供一个非常优雅的解决方案(代码比jq
少得多)。
我假设您的'members.txt'。
首先为每个要创建的json对象创建一个序列:
xidel -s members.txt --xquery 'tokenize($raw,"\n\n")'
或者...
xidel -s members.txt --xquery 'tokenize($raw,"\n\n") ! (position(),.)'
1
id = 1
fname = Leif
gname = Håkansson
genderid = 1
2
id = 2
fname = Yvonne
gname = Bergman
genderid = 2
3
id = 3
fname = Roger
gname = Sjöberg
genderid = 1
...以便更好地向您展示序列中的各个项目。
现在您有3个多行字符串。要将每个项目/字符串转换为另一个序列,其中每个项目都是新行:
xidel -s members.txt --xquery 'tokenize($raw,"\n\n") ! x:lines(.)'
({x:lines(.)
是tokenize(.,'\r\n?|\n')
的简写)
现在,每行标记“ =”(这会创建另一个序列)并将其保存到变量中。例如,对于第一行,此序列为("id","1")
,对于第二行,{序列为("fname","Leif")
,依此类推:
xidel -s members.txt --xquery 'tokenize($raw,"\n\n") ! (for $x in x:lines(.) let $a:=tokenize($x," = ") return ($a[1],$a[2]))'
最后删除前导空格(normalize-space()
),创建json对象({| {key-value-pair} |}
)并将所有json对象放入数组([ ... ]
):
xidel -s members.txt --xquery '[tokenize($raw,"\n\n") ! {|for $x in x:lines(.) let $a:=tokenize($x," = ") return {normalize-space($a[1]):$a[2]}|}]'
美化+输出:
xidel -s members.txt --xquery '
[
tokenize($raw,"\n\n") ! {|
for $x in x:lines(.)
let $a:=tokenize($x," = ")
return {
normalize-space($a[1]):$a[2]
}
|}
]
'
[
{
"id": "1",
"fname": "Leif",
"gname": "Håkansson",
"genderid": "1"
},
{
"id": "2",
"fname": "Yvonne",
"gname": "Bergman",
"genderid": "2"
},
{
"id": "3",
"fname": "Roger",
"gname": "Sjöberg",
"genderid": "1"
}
]
注意:对于xidel-0.9.9.7173
和更高版本的--json-mode=deprecated
,需要使用[
]
创建一个json数组。创建json数组的新(XQuery 3.1)方法是使用array{
}
。