Управление отметками времени объекта 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"
                 }
             ]
}

У меня есть этот объект JSON, и я хочу перебрать каждый объект и обновить метку времени до более удобочитаемой даты. Прямо сейчас у меня есть

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

Но когда я прочитал объект $currentLogs, он все еще не обновился.

2 ответа

Вам нужно будет сначала проанализировать дату и время, а затем применить желаемое форматирование. Если вы не применяете форматирование, то timestampСвойство будет типом объекта, и обратное преобразование в JSON приведет к странному форматированию. Лучше всего сделать ваш новый формат строкой, чтобы он не управлялся сериализацией JSON:

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

В своей попытке вы использовали следующий код:

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

Использование окружающих {}обозначает блок скрипта. Если этот блок сценария не вызывается или не вызывается, он просто выводит его содержимое дословно. Вы можете запустить приведенный выше код в консоли и увидеть результат.

Вы также не отформатировали свой объект после попытки синтаксического анализа. По умолчанию вывод в консоли будет применять ToString() неявно, когда datetime value установлено в свойство, но это неявное форматирование не преобразуется в преобразование JSON (по какой-либо причине).

Спасибо, что показали желаемый формат.

Чтобы обновить те элементы, у которых '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'

Другие вопросы по тегам