Задача Powershell ConvertTo-Json с двойными кавычками - PullRequest
2 голосов
/ 19 сентября 2019

Я пытаюсь преобразовать текстовый файл в строку в формате JSON, но двойные кавычки расположены неправильно.

My file.txt содержит следующую структурированную информацию(две пустые строки в начале):

<code></p>

<p>adapter_name          : empty1
route_age             : 10
route_nexthop         : 172.0.0.1
route_protocol        : NETMGMT1
speed                 : null </p>

<p>adapter_name          : empty2
route_age             : 100
route_nexthop         : 172.0.0.2
route_protocol        : NETMGMT2
speed                 : null </p>

<p>adapter_name          : empty3
route_age             : 1000
route_nexthop         : 172.0.0.3
route_protocol        : NETMGMT3
speed                 : null 

Мой код:

$data = Get-Content C:\scripts\file.txt | %{$_.PSObject.BaseObject}
$data | ConvertTo-Json 

Без этой части:

<code>%{$_.PSObject.BaseObject}
Это просто нисходящийглубоко в дерево объектов, что может занять много времени.

Фактический результат:

<code>
    [
        "",
        "",
        "adapter_name          : empty1",
        "route_age             : 10",
        "route_nexthop         : 172.0.0.1",
        "route_protocol        : NETMGMT1",
        "speed                 : null "
        "",
        "adapter_name          : empty2",
        "route_age             : 100",
        "route_nexthop         : 172.0.0.2",
        "route_protocol        : NETMGMT2",
        "speed                 : null "
        "",
        "adapter_name          : empty3",
        "route_age             : 1000",
        "route_nexthop         : 172.0.0.3",
        "route_protocol        : NETMGMT3",
        "speed                 : null "
    ]

И ожидаемый результат:

[
  {
    "adapter_name"         : "empty1",
    "route_age"            : 10,
    "route_nexthop"        : "172.0.0.1",
    "route_protocol"       : "NETMGMT1",
    "speed"                : null
  },
  {
    "adapter_name"         : "empty2",
    "route_age"            : 100,
    "route_nexthop"        : "172.0.0.2",
    "route_protocol"       : "NETMGMT2",
    "speed"                : null
  },
  {
    "adapter_name"         : "empty3",
    "route_age"            : 1000,
    "route_nexthop"        : "172.0.0.3",
    "route_protocol"       : "NETMGMT3",
    "speed"                : null
  }
]

Примеры 4 и 5 в ссылке https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/convertto-json?view=powershell-6 показывает, как использовать командлет ConvertoTo-Json в аналогичной ситуации, но без проблем.

1 Ответ

1 голос
/ 19 сентября 2019

Get-Content просто возвращает отдельные строки из текстового файла, он ничего не знает о любой структуре, которая может быть закодирована в этих строках.

Следовательно, вы просто конвертируете строки как есть в JSON, что приводит к простому списку строковых значений JSON, которые вы видите.

Чтобы решить эту проблему, вы должны выполнить собственный анализ текстового файла в структурированные объекты (хеш-таблицы), блок за блоком ипередать их в ConvertTo-Json:

# Read the input file as a whole (-Raw) and split it into blocks (paragraphs)
(Get-Content -Raw C:\scripts\file.txt) -split '\r?\n\r?\n' -ne '' |
  ForEach-Object { # Process each block
    # Initialize an ordered hashtable for the key-values pairs in this block.
    $oht = [ordered] @{}
    # Loop over the block's lines.
    foreach ($line in $_ -split '\r?\n' -ne '') {
      # Split the line into key and value...
      $key, $val = $line -split ':', 2
      # ... and add them to the hashtable.
      $oht[$key.Trim()] = $val.Trim()
    }
    $oht # Output the hashtable.
  } | ConvertTo-Json

Вышеприведенный вывод дает желаемый результат.


В качестве отступления, re:

Без этой части:
%{$_.PSObject.BaseObject}
Он просто очень глубоко спускается в дерево объектов, что может занять много времени.

Проблема в том, что Get-Content украшает строки, которые он выводит, дополнительными,обычно невидимые свойства, предоставляющие информацию о происхождении, например путь файла, из которого были прочитаны строки.

Эти обычно скрытые свойства неожиданно появляются в сценариях сериализации, например, когда ConvertTo-Json

Приведенное выше решение неявно обходит эту проблему, поскольку во время обработки создаются новые строки.

Хотя дополнительные свойства могут быть полезны, они частоне только не нужно, но и медленно Get-Content down.

  • В этом выпуске GitHub предлагается добавить переключатель к Get-Content, который позволяет отказаться с оформлением линий (не реализовано в PowerShell Core 7.0.0-preview.3)

  • В дополнение, эта проблема GitHub предполагает добавление PowerShellсвойства должны игнорироваться для типов, которые соответствуют примитивным типам JSON, включая [string] (не реализовано в PowerShell Core 7.0.0-preview.3)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...