【问题标题】:Powershell ConvertTo-Json problem with double-quotation marks带有双引号的Powershell ConvertTo-Json问题
【发布时间】:2019-09-18 23:33:06
【问题描述】:

我正在尝试将文本文件转换为 JSON 格式的字符串,但双引号的位置不正确。

我的 file.txt 包含以下结构化信息(开头也有两个空行):



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

我的代码是:

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

没有这部分:

%{$_.PSObject.BaseObject}
它只是深入到对象树中,这可能需要很长时间。

实际结果是:


    [
        "",
        "",
        "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
  }
]

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/convertto-json?view=powershell-6 链接中的示例 4 和 5 显示了如何在类似情况下使用 cmdlet ConvertoTo-Json,但没有问题。

【问题讨论】:

    标签: powershell


    【解决方案1】:

    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
    

    以上产生了所需的输出。


    顺便说一句,回复:

    没有这部分:
    %{$_.PSObject.BaseObject}
    它只是深入到对象树中,这可能需要很长时间。

    问题在于Get-Content 用额外的通常不可见的属性来装饰它输出的行,这些属性提供原始信息,例如读取行的文件的路径。

    这些通常隐藏的属性在序列化场景中会意外出现,例如在使用 ConvertTo-Json 时。

    上面的解决方案隐式绕过了这个问题,因为在处理过程中正在创建 new 字符串。

    虽然附加属性可能很有用,但它们通常不仅不需要,而且还会降低Get-Content 的速度。

    • This GitHub issue 建议向Get-Content 添加一个开关,允许选择退出装饰线条(从 PowerShell Core 7.0.0-preview.3 开始未实现)

    • 作为补充,this GitHub issue 建议忽略与原始 JSON 类型相对应的类型的 PowerShell 添加属性,其中包括 [string](未在 PowerShell Core 7.0.0-preview.3 中实现)

    【讨论】:

      猜你喜欢
      • 2022-10-17
      • 1970-01-01
      • 2017-05-13
      • 2013-02-28
      • 2015-06-01
      • 2014-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多