如何重新格式化和转换jq的输出?

时间:2017-09-12 06:15:14

标签: json bash shell jq

我有一个json字符串如下:

    [{
        "appId": "server1",
        "userName": "bhavik",
        "scaleApp": {
            "imageName": "${DATA}/build-server:1",
            "internalPath": "/",
            "volumesFrom": [
                "${DATA}/buildtype-mock:219",
                "${DATA}/buildtype-se:543-1.0.5-V30.2-GA"
            ]
        }
    },
    {
        "appId": "server2",
        "userName": "rajiv",
        "scaleApp": {
            "imageName": "${DATA}/build-server:159",
            "internalPath": "/",
            "volumesFrom": [
                "${DATA}/buildtype-mock:218",
                "${DATA}/buildtype-se:540-1.0.5-V30.1-GA",
                "${DATA}/buildtype-nodejs:42",
                "${DATA}/buildtype-flogo:682"
            ]
        }
    }
]

我需要输出如下:

{
"imageName" : "build-server:159",
"volumesFrom" : [
        "buildtype-mock:218",
        "buildtype-se:540-1.0.5-V30.1-GA",
        "buildtype-nodejs:42",
        "buildtype-flogo:682"
      ]
}

我正在尝试用jq来实现它。我使用以下命令:

jq '.[] | { imageName: .scaleApp.imageName,volumesFrom: .scaleApp.volumesFrom } ' data.json

以下是输出:

{
  "imageName": "${DATA}/build-server:159",
  "volumesFrom": [
        "${DATA}/buildtype-mock:218",
        "${DATA}/buildtype-se:540-1.0.5-V30.1-GA",
        "${DATA}/buildtype-nodejs:42",
        "${DATA}/buildtype-flogo:682"
      ]
}

我没有得到我想要的正确格式,任何人都可以帮助我。

1 个答案:

答案 0 :(得分:3)

这是原始问题的解决方案。如果以下过滤器位于filter.jq

  .scaleApp
| {imageName, volumesFrom}
| .imageName |= .[8:]
| .volumesFrom[] |= .[8:]

以及以下(原始)样本数据

{
  "appId": "server1",
  "userName": "bhavik",
  "scaleApp": {
    "imageName": "${DATA}/build-server:159",
    "internalPath": "/",
    "volumesFrom": [
      "${DATA}/buildtype-mock:218",
      "${DATA}/buildtype-se:540-1.0.5-V30.1-GA",
      "${DATA}/buildtype-nodejs:42",
      "${DATA}/buildtype-flogo:682"
    ]
  }
}

data.json然后是命令

$ jq -M -f filter.jq data.json

产生

{
  "imageName": "build-server:159",
  "volumesFrom": [
    "buildtype-mock:218",
    "buildtype-se:540-1.0.5-V30.1-GA",
    "buildtype-nodejs:42",
    "buildtype-flogo:682"
  ]
}

以下是修订问题的解决方案。假设以下样本数据位于data.json

[
  {
    "appId": "server1",
    "userName": "bhavik",
    "scaleApp": {
      "imageName": "${DATA}/build-server:1",
      "internalPath": "/",
      "volumesFrom": [
        "${DATA}/buildtype-mock:219",
        "${DATA}/buildtype-se:543-1.0.5-V30.2-GA"
      ]
    }
  },
  {
    "appId": "server2",
    "userName": "rajiv",
    "scaleApp": {
      "imageName": "${DATA}/build-server:159",
      "internalPath": "/",
      "volumesFrom": [
        "${DATA}/buildtype-mock:218",
        "${DATA}/buildtype-se:540-1.0.5-V30.1-GA",
        "${DATA}/buildtype-nodejs:42",
        "${DATA}/buildtype-flogo:682"
      ]
    }
  }
]

filter.jq

map(      
  .scaleApp
| {imageName, volumesFrom}
| .imageName |= .[8:]
| .volumesFrom[] |= .[8:]
)

产生

[
  {
    "imageName": "build-server:1",
    "volumesFrom": [
      "buildtype-mock:219",
      "buildtype-se:543-1.0.5-V30.2-GA"
    ]
  },
  {
    "imageName": "build-server:159",
    "volumesFrom": [
      "buildtype-mock:218",
      "buildtype-se:540-1.0.5-V30.1-GA",
      "buildtype-nodejs:42",
      "buildtype-flogo:682"
    ]
  }
]

这比你要求的更多filter.jq

map(      
   select(.appId == "server2")
|  .scaleApp
| {imageName, volumesFrom}
| .imageName |= .[8:]
| .volumesFrom[] |= .[8:]
)[]

仅生成

{
  "imageName": "build-server:159",
  "volumesFrom": [
    "buildtype-mock:218",
    "buildtype-se:540-1.0.5-V30.1-GA",
    "buildtype-nodejs:42",
    "buildtype-flogo:682"
  ]
}

代表.appId == "server2"