【问题标题】:Manipulate timestamps of JSON object操作 JSON 对象的时间戳
【发布时间】:2021-10-06 07:36:33
【问题描述】:
{
    "logs":  [
                 {
                     "timestamp":  "20181216T14:36:12",
                     "description":  "IP connectivity via interface ipmp1 has become degraded.",
                     "type":  "alert",
                     "uuid":  "1234567",
                     "severity":  "Minor"
                 },
                 {
                     "timestamp":  "20181216T14:38:16",
                     "description":  "Network connectivity via port ibp4 has been established.",
                     "type":  "alert",
                     "uuid":  "12345678",
                     "severity":  "Minor"
                 }
             ]
}

我有这个 JSON 对象,我想遍历每个对象并将时间戳更新为更易读的日期。现在,我有

$currentLogs.logs |
Where{$_.type -eq 'alert'} |
ForEach{$_.timestamp = {[datetime]::parseexact($_.timestamp, 'yyyyMMdd\THH:mm:ss', $null)}}

但是当我读取对象 $currentLogs 时,它仍然没有更新。

【问题讨论】:

  • 您将$_.timestamp 设置为一个脚本块并且从未执行该脚本块。另外,除非您希望将默认格式应用于您的值的数据类型,否则您仅尝试解析该值并没有在解析后提供新格式。
  • 删除= 之后的{ } 大括号,围绕parseexact() 行中的parseexact() 命令
  • 什么是“更易读的日期”格式?
  • @Theo 希望它显示 'yyyy-MM-dd HH:mm:ss'

标签: arrays json powershell foreach convertto-json


【解决方案1】:

您需要先解析日期/时间,然后应用所需的格式。如果您不应用任何格式,则timestamp 属性将是datetime 对象类型,并且转换回JSON 将对它进行奇怪的格式设置。最好将您的新格式设置为字符串,这样它就不会被 JSON 序列化操作:

$currentLogs.logs | Where type -eq 'alert' | ForEach-Object {
    $_.timestamp = [datetime]::parseexact($_.timestamp, 'yyyyMMddTHH:mm:ss', $null).ToString('yyyy-MM-dd HH:mm:ss')
}

在您的尝试中,您使用了以下代码:

{[datetime]::parseexact($_.timestamp, 'yyyyMMdd\THH:mm:ss', $null)}

使用环绕的{} 表示一个脚本块。如果没有调用或调用该脚本块,它只会逐字输出其内容。您可以在控制台中运行上述代码并查看结果。

您也没有在解析尝试后格式化您的 datetime 对象。默认情况下,当datetime 值设置为属性时,控制台中的输出将隐式应用ToString(),但该隐式格式不会转换为您的JSON 转换(无论出于何种原因)。

【讨论】:

  • 您好,我实现了该代码块,它仍在逐字返回内容。我说的时间戳对吗?
  • 确保您没有在 [datetime]::parseexact() 表达式周围使用 {}
【解决方案2】:

感谢您显示所需的格式。

要更新 'type' 等于 'alert' 的元素,您可以这样做:

$json = @'
{
    "logs":  [
                 {
                     "timestamp":  "20181216T14:36:12",
                     "description":  "IP connectivity via interface ipmp1 has become degraded.",
                     "type":  "alert",
                     "uuid":  "1234567",
                     "severity":  "Minor"
                 },
                 {
                     "timestamp":  "20181216T14:38:16",
                     "description":  "Network connectivity via port ibp4 has been established.",
                     "type":  "alert",
                     "uuid":  "12345678",
                     "severity":  "Minor"
                 }
             ]
}
'@ | ConvertFrom-Json

# find the objects with 'type' equals 'alert'
$json.logs | Where-Object { $_.type -eq 'alert' } | ForEach-Object { 
    # parse the date in its current format
    $date = [datetime]::ParseExact($_.timestamp, 'yyyyMMddTHH:mm:ss', $null)
    # and write back with the new format
    $_.timestamp = '{0:yyyy-MM-dd HH:mm:ss}' -f $date
}

# convert back to json
$json | ConvertTo-Json

如果您想保存到文件,请在上面的最后一行添加| Set-Content -Path 'X:\Path\To\Updated.json'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    相关资源
    最近更新 更多