根据模式分割文件

时间:2018-10-30 21:46:54

标签: json bash awk

我有一个curl命令的一部分生成的JSON输出,并且想要根据模式分割结果文件:

文件内容看起来像

{
"clusters" : [ {
"name" : "subject",
"version" : "XXX",
"services" : [ {
  "name" : "initiator",
  "config" : {
    "items" : [ {
      "name" : "enableSecurity",
      "value" : "true",
      "sensitive" : false
    }, {
      "name" : "service_config_suppression_server_count_validator",
      "value" : "true",
      "sensitive" : false
    } ]
  },
  "roles" : [ {
    "name" : "intiator-role1",
    "type" : "SERVER",
    "hostRef" : {
      "hostId" : "754389-8989db-8743ty"
    },
    "config" : {
      "items" : [ {
        "name" : "role_creds",
        "value" : "sdfujnvhdsg87909",
        "sensitive" : true
      }, {
        "name" : "serverId",
        "value" : "1",
        "sensitive" : false
      } ]
    },
    "roleConfigGroupRef" : {
      "roleConfigGroupName" : "initiator-group"
    }
  } ]
} ]
},
....bunch of lines in between
..........

 {
  "name" : "subject2",
  "version" : "XXX",
"services" : [ {
  "name" : "ingestor",
  "config" : {
    "items" : [ ]
  },
  "roles" : [ {
    "name" : "ingestor-role1",
    "type" : "service",
    "hostRef" : {
      "hostId" : "754389-8989db-8743ty"
    },
    "config" : {
      "items" : [ {
        "name" : "role_code",
        "value" : "sdfujnvhdsg67340",
        "sensitive" : true
      } ]
    },
    "roleConfigGroupRef" : {
      "roleConfigGroupName" : "ingestor-group"
    }
  } ]
  } ]
  }
  ]
  }

每当重复字符串“版本”:“ XXX”时,我都希望将此文件拆分为不同的文件。因此,生成的文件应具有从字符串前两行开始到下一个字符串出现的内容。

这只是摘录自一个巨大的json文件,在此数据集中,我只保留了两个字符串模式,因此期望两个文件的内容如下:

文件1应该具有:

"clusters" : [ {
"name" : "subject",
"version" : "XXX",
"services" : [ {
  "name" : "initiator",
  "config" : {
    "items" : [ {
      "name" : "enableSecurity",
      "value" : "true",
      "sensitive" : false
    }, {
      "name" : "service_config_suppression_server_count_validator",
      "value" : "true",
      "sensitive" : false
    } ]
  },
  "roles" : [ {
    "name" : "intiator-role1",
    "type" : "SERVER",
    "hostRef" : {
      "hostId" : "754389-8989db-8743ty"
    },
    "config" : {
      "items" : [ {
        "name" : "role_creds",
        "value" : "sdfujnvhdsg87909",
        "sensitive" : true
      }, {
        "name" : "serverId",
        "value" : "1",
        "sensitive" : false
      } ]
    },
    "roleConfigGroupRef" : {
      "roleConfigGroupName" : "initiator-group"
    }
  } ]
} ]
},
....bunch of lines in between
..........

文件2应该具有

 {
  "name" : "subject2",
  "version" : "XXX",
"services" : [ {
  "name" : "ingestor",
  "config" : {
    "items" : [ ]
  },
  "roles" : [ {
    "name" : "ingestor-role1",
    "type" : "service",
    "hostRef" : {
      "hostId" : "754389-8989db-8743ty"
    },
    "config" : {
      "items" : [ {
        "name" : "role_code",
        "value" : "sdfujnvhdsg67340",
        "sensitive" : true
      } ]
    },
    "roleConfigGroupRef" : {
      "roleConfigGroupName" : "ingestor-group"
    }
  } ]
  } ]
  }
  ]
  }

希望通过bash,最好是awk来实现这一目标,

2 个答案:

答案 0 :(得分:2)

我认为在这种情况下,您最好的选择是使用jqhttps://stedolan.github.io/jq/download/

jq允许您操纵和查询任何JSON内容。

已更新:

我在上面编辑了您的源JSON,因此它实际上是有效的JSON,这些是我用来获取jq的命令,用于为我提供clusters数组中的每个元素:

 jq '.["clusters"] | .[0]' test.json

 jq '.["clusters"] | .[1]' test.json

当然,您可以根据需要编写脚本。无需搜索version="XXX"文本,因为它们都是clusters数组中的简单元素。

答案 1 :(得分:0)

如果您只想在每次“版本”重复时将文件拆分为一个新文件,并在“版本”之前以2行开头和结尾,则可以执行以下操作:

#!/bin/bash
awk '
BEGIN {
    i = 0
}
{   
    prevLn2 = prevLn1
    prevLn1 = currentLn
    currentLn = $0

    if(currentLn ~ /^[ ]{0,}\"version\"/) {
        i++
    }

    if(i > 0) {
        print prevLn2 >> "file" i ".txt"
    }
}
'

这会将前两行保存在变量prevLn1和prevLn2中,对于输入中的每一行,检查当前行是否与正则表达式^[ ]{0,}\"version\"相匹配-表示该行的开头,然后是零个或多个空格,和文字文本“版本”。如果匹配,则增加变量i。然后将第二行添加到以变量i命名的文件。

将代码保存在文件中,例如splitfile.sh,并使其可执行chmod 755 splitfile.sh。 用法:./splitfile.sh < jsonfile.txt将在同一目录中生成文件file1.txt,file2.txt,file3.txt...。