使用 jq 从文本输入嵌套 json
nested json from text input using jq
我的文本数据看起来像(space 分隔的片段):
第一行是 header:
name type input file th repeatNumber
S1 class [12,7,6,19] sfile1 -10 2
S2 class [12,7,6,19] sfile2 -5 1
S3 bottom [12,7,16] sfile3 -15 1
使用 shell 脚本或命令行(最好使用 jq)想要将其转换为一个嵌套的 json,看起来像:
'dets':{
'S1':{
'type':'class',
'input': [12,7,6,19],
'config':{
'file':'sfile1',
'th': -10
}
},
'S2':{
'type':'class',
'input': [12,7,6,19],
'config':{
'file':'sfile2',
'th': -5
}
},
'S3':{
'type':'bottom',
'input': [12,7,16],
'config':{
'file':'sfile3',
'th': -15
}
}
}
使用 jq 解决问题的适当方法与使用 awk
基本相同:对于每个输入行(第一行除外),解析它并发出相应的 JSON object。为了清楚起见,让我们定义一个函数来处理每个输入行(作为字符串读入):
def parse:
[splits(" +")]
| {(.[0]) : {type: .[1],
input: (.[2] | fromjson),
config: { file: .[3],
th: .[4] }} };
解决方案很简单:
{ dets: [inputs | parse] | add }
jq 的适当调用如下所示:
jq -R -f program.jq input.txt
请注意,此处省略 -n
command-line 选项具有跳过 header 行的效果。
此调用将产生如下所示的 JSON。请注意,问题中显示为 JSON 的文本严格来说不是 JSON,但由于声明的目标是产生 JSON,我们将保留它。
注意事项
上述解决方案做出了各种假设,特别是:
1) 字段在匹配正则表达式“+”的意义上是"space-separated";特别是,假定数组在没有任何嵌入空间的情况下呈现。
2)"input"字段可以使用fromjson
解析;如果对此有任何疑问,请改用 (fromjson? // .)
。
输出
{
"dets": {
"S1": {
"type": "class",
"input": [
12,
7,
6,
19
],
"config": {
"file": "sfile1",
"th": "-10"
}
},
"S2": {
"type": "class",
"input": [
12,
7,
6,
19
],
"config": {
"file": "sfile2",
"th": "-5"
}
},
"S3": {
"type": "bottom",
"input": [
12,
7,
16
],
"config": {
"file": "sfile3",
"th": "-15"
}
}
}
}
我的文本数据看起来像(space 分隔的片段): 第一行是 header:
name type input file th repeatNumber
S1 class [12,7,6,19] sfile1 -10 2
S2 class [12,7,6,19] sfile2 -5 1
S3 bottom [12,7,16] sfile3 -15 1
使用 shell 脚本或命令行(最好使用 jq)想要将其转换为一个嵌套的 json,看起来像:
'dets':{
'S1':{
'type':'class',
'input': [12,7,6,19],
'config':{
'file':'sfile1',
'th': -10
}
},
'S2':{
'type':'class',
'input': [12,7,6,19],
'config':{
'file':'sfile2',
'th': -5
}
},
'S3':{
'type':'bottom',
'input': [12,7,16],
'config':{
'file':'sfile3',
'th': -15
}
}
}
使用 jq 解决问题的适当方法与使用 awk
基本相同:对于每个输入行(第一行除外),解析它并发出相应的 JSON object。为了清楚起见,让我们定义一个函数来处理每个输入行(作为字符串读入):
def parse:
[splits(" +")]
| {(.[0]) : {type: .[1],
input: (.[2] | fromjson),
config: { file: .[3],
th: .[4] }} };
解决方案很简单:
{ dets: [inputs | parse] | add }
jq 的适当调用如下所示:
jq -R -f program.jq input.txt
请注意,此处省略 -n
command-line 选项具有跳过 header 行的效果。
此调用将产生如下所示的 JSON。请注意,问题中显示为 JSON 的文本严格来说不是 JSON,但由于声明的目标是产生 JSON,我们将保留它。
注意事项
上述解决方案做出了各种假设,特别是:
1) 字段在匹配正则表达式“+”的意义上是"space-separated";特别是,假定数组在没有任何嵌入空间的情况下呈现。
2)"input"字段可以使用fromjson
解析;如果对此有任何疑问,请改用 (fromjson? // .)
。
输出
{
"dets": {
"S1": {
"type": "class",
"input": [
12,
7,
6,
19
],
"config": {
"file": "sfile1",
"th": "-10"
}
},
"S2": {
"type": "class",
"input": [
12,
7,
6,
19
],
"config": {
"file": "sfile2",
"th": "-5"
}
},
"S3": {
"type": "bottom",
"input": [
12,
7,
16
],
"config": {
"file": "sfile3",
"th": "-15"
}
}
}
}