使用 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"
      }
    }
  }
}