【问题标题】:jq: create array of object in json and insert the new object each time bash scripts executes [duplicate]jq:在json中创建对象数组并在每次bash脚本执行时插入新对象[重复]
【发布时间】:2020-05-16 02:53:33
【问题描述】:

我想在 bash 中使用 jq 创建有效的 json。 每次 bash 脚本执行“将新元素添加到现有 JSON 数组”时,如果文件为空,则创建新文件。

我正在使用以下 jq 命令来创建我的 json(不完整,请帮我完成)

$jq -n -s '{service: $ARGS.named}' \
         --arg transcationId $TRANSACTION_ID_METRIC '{"transcationId":"\($transcationId)"}' \
         --arg name $REALPBPODDEFNAME '{"name ":"\($name )"}'\
         --arg lintruntime $Cloudlintruntime '{"lintruntime":"\($lintruntime)"}' \
         --arg status $EXITCODE '{"status":"\($status)"}' \
         --arg buildtime $totaltime '{"buildtime":"\($buildtime)"}' >> Test.json

产生像

这样的输出

{
  "service": {
    "transcationId": "12345",
    "name": "sdsjkdjsk",
    "lintruntime": "09",   
    "status": "0",
    "buildtime": "9876"
  }
}
{
  "service": {
    "transcationId": "123457",
    "servicename": "sdsjkdjsk",
    "lintruntime": "09",   
    "status": "0",
    "buildtime": "9877"
  }
}

但我不想以这种格式输出

json 应该像第一次创建一样

在jason下面创建的jq命令应该是什么

{ 
   "ServiceData":{ 
      "date":"30/1/2020",
      "ServiceInfo":[ 
         { 
            "transcationId":"20200129T130718Z",
            "name":"MyService",
            "lintruntime":"178",
            "status":"0",
            "buildtime":"3298"
         }
      ]
   }
}

当我下次执行 bash 脚本元素时,应该像

一样将元素添加到数组中

什么是jq命令获取这种格式的json

{ 
   "ServiceData":{ 
      "date":"30/1/2020",
      "ServiceInfo":[ 
         { 
            "transcationId":"20200129T130718Z",
            "name":"MyService",
            "lintruntime":"16",
            "status":"0",
            "buildtime":"3256"
         },
         { 
            "transcationId":"20200129T130717Z",
            "name":"MyService",
            "lintruntime":"16",
            "status":"0",
            "buildtime":"3256"
         }
      ]
   }
}

我也想要“日期”、“服务数据”、“服务信息”
我当前的json中缺少的字段

【问题讨论】:

标签: bash jq


【解决方案1】:

您不会为每个 --arg 选项提供单独的过滤器;它只是定义了 a 变量,可以在 single 过滤器参数中使用。您只想将新对象添加到您的输入中。 jq 不进行就地文件编辑,因此您必须写入一个临时文件并在事后替换您的原始文件。

jq --arg transactionId "$TRANSACTION_ID_METRIC" \
   --arg name "$REALPBPODDEFNAME" \
   --arg lintruntime "$Cloudlintruntime" \
   --arg status "$EXITCODE" \
   --arg buildtime "$totaltime" \
   '.ServiceData.ServiceInfo += [ {transactionID: $transactionId,
                                   name: $name,
                                   lintruntime: $lintruntime,
                                   status: $status,
                                   buildtime: $buildtime
                                   }]' \
    Test.json > tmp.json &&
 mv tmp.json Test.json

这是相同的命令,但使用一个数组来存储所有--arg 选项和一个变量来存储过滤器,因此命令行更简单一些。 (您也不需要在数组定义中显式续行。)

args=(
   --arg transactionId "$TRANSACTION_ID_METRIC"
   --arg name "$REALPBPODDEFNAME"
   --arg lintruntime "$Cloudlintruntime"
   --arg status "$EXITCODE"
   --arg buildtime "$totaltime"
)

filter='.ServiceData.ServiceInfo += [
    {
      transactionID: $transactionId,
      name: $name,
      lintruntime: $lintruntime,
      status: $status,
      buildtime: $buildtime
    }
]'

jq "${args[@]}" "$filter" Test.json > tmp.json && mv tmp.json Test.json

【讨论】:

  • 不知何故,上面的代码无法正常工作............ error jq: error: $transactionId is not在 第 1 行定义: .ServiceData.ServiceInfo += [ {transactionId: $transactionId, jq: 1 compile error
  • 我对 bash 脚本完全陌生 .. 所以不知道如何解决它
  • 我的命令是........cat metricData.json | $jq --arg transcationId "${TRANSACTION_ID_METRIC}" \ '.ServiceData.ServiceInfo += [{"transcationID": $transactionId}]' >tmp.json && mv tmp.json metricData.json ....... .....它给出了问题......................jq:错误:$transactionId 未在 行定义1: .ServiceData.ServiceInfo += [{"transcationID": $transactionId}]
  • 只是我的一个错字;我在transaction 中交换了ac
  • @chepner 我在不同的 linux VM 上尝试过,它给出了 tmp.json: Permission denied 你知道我为什么会看到这个
猜你喜欢
  • 2018-10-19
  • 1970-01-01
  • 2021-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多