jq:在路径上带有正则表达式的setpaths,如何处理以整数结尾并产生错误的路径?

时间:2019-05-07 10:22:32

标签: json jq

我有以下对象:

{
  "domainId": "hidden",
  "lastUsed": "Thu Oct 04 2018",
  "lastUsedTimestamp": 1538673002460,
  "users": [
    {
      "userId": "hidden",
      "lastUsedTimestamp": 1538673002460
    },
    {
      "userId": "hidden",
      "lastUsedTimestamp": 1536087726701
    },
    {
      "userId": "hidden",
      "lastUsedTimestamp": 1536086675399
    },
    {
      "userId": "hidden",
      "lastUsedTimestamp": 1536182646984
    }
  ]
}

我想将所有lastUsedTimestamp值都转换为日期。这适用于:

reduce (paths | select(.[-1] == "lastUsedTimestamp")) as $p 
  (.;setpath($p; getpath($p) / 1000 | todate))

但是如果我在对象的其他位置有其他时间戳记键,例如createdTimestampstartTimestamp怎么办?例如:

{
  "domainId": "hidden",
  "lastUsed": "Thu Oct 04 2018",
  "lastUsedTimestamp": 1538673002460,
  "users": [
    {
      "userId": "hidden",
      "lastUsedTimestamp": 1538673002460
    },
    {
      "userId": "hidden",
      "lastUsedTimestamp": 1536087726701
    },
    {
      "userId": "hidden",
      "lastUsedTimestamp": 1536086675399,
      "createdTimestamp": 1536086675399
    },
    {
      "userId": "hidden",
      "lastUsedTimestamp": 1536182646984,
      "startTimestamp": 1536182646984
    }
  ]
}

我尝试过

reduce (paths | select(.[-1] | endswith("Timestamp")) as $p 
  (.;setpath($p; getpath($p) / 1000 | todate))

或带有test的等效项,但是以整数结尾的路径会使它失败。

我该如何解决?

2 个答案:

答案 0 :(得分:2)

要抑制错误,请使用... ?运算符,该运算符是try ...的简写。例如:

reduce (paths|select(.[-1]|endswith("Timestamp")?)) as $p
(.; setpath($p; getpath($p)/1000|todate))

答案 1 :(得分:1)

对于这种类型的问题,walk/1通常很方便:

def timestamps:
  with_entries(if .key | endswith("Timestamp")
               then .value |= (./1000 | todate) else . end);

walk( if type == "object" then timestamps else . end )

单线

如果您想要单线:

walk( if type == "object" then with_entries(if .key | endswith("Timestamp") then .value |= (./1000 | todate) else . end) else . end)

如果您的jq允许省略else .,这将变得更容易理解:

walk(if type == "object" then with_entries(if .key | endswith("Timestamp") then .value |= (./1000 | todate) end) end)