【问题标题】:Powershell - Search json treePowershell - 搜索 json 树
【发布时间】:2020-06-23 18:39:26
【问题描述】:

我在 my.json 文件中有一个 json 结构,如下所示:

{
   "key1":{
      "key1A":{
         "someKey":"someValue"
      },
      "key1B":{
         "someKey":"someValue"
      }
   },
   "key2":{
      "key2A":{
         "someKey":"someValue"
      },
      "key2B":{
         "someKey":"someValue"
      }         
   },       
   "key3":{
      "key3A":{
         "someKey":"someValue"
      },
      "key3B":{
         "someKey":"someValue"
      }
   }
} 

使用 powershell 我想搜索“node”key1B 并选择它。假设是

  1. key1B 在整个树中只出现一次
  2. 搜索词 (key1B) 可以是根元素或根元素的子元素。

如果我要知道 key1B 在哪个节点下的父节点,我可以在下面使用:

Get-Content -Raw my.json | ConvertFrom-Json | Select-Object -ExpandProperty key1 | Select-Object -ExpandProperty key1B

如何使上面的选择通用,以便我正在搜索的节点可以位于根节点或根节点的子节点中?

【问题讨论】:

  • 你的 JSON 语法不正确,"key1""key2" 都没有关闭 }
  • @NekoMusume 抱歉,已修复。
  • 试试((Get-Content -Raw my.json | ConvertFrom-Json) | gm | ? {$_.Definition -imatch "key1A"}).name 这样会得到key1A的父节点
  • 能够使用您的 JSON 获取 key1a 的内容为 $testJson,如下所示:$($testJson | ConvertFrom-Json).$((($testJson | ConvertFrom-Json) | gm | ? {$_.Definition -imatch "key1A"}).name).key1a 非常令人困惑,但如果我有一个带有实际转换的 json 的单独变量会更容易,证明概念虽然

标签: json powershell psobject select-object


【解决方案1】:
# convert as a Hashtable
$json = Get-Content -Raw .\my.json | ConvertFrom-Json -AsHashtable

# a root element
$json.key1B

# a child of a root element
$json.Values.key1B

# descendant
function findByKey {
  param($json, $key)
  if ($json.$key) { $json.$key }
  else {
    $json.Values | ? values | % { findByKey $_ $key } | select -First 1
  }
}

findByKey $json "key1B"

【讨论】:

  • 唯一需要powershell 7.
【解决方案2】:

jq 有一个 recursive descent .. 运算符,可以搜索所有键,如 xpath //

get-content file.json | jq '.. | .key1B? | select(. != null)'

{
  "someKey1b": "someValue1b"
}

【讨论】:

  • jq 是别名吗?我的系统找不到jq
  • @NekoMusume 不,这是要下载的外部命令。
【解决方案3】:

您可以通过查看Get-Member 的定义列找到Key1A 或您要查找的任何键。

让我们将您的 JSON 定义为变量 $TestJson

$testJson = @"
{
   "key1":{
      "key1A":{
         "someKey":"someValue"
      },
      "key1B":{
         "someKey":"someValue"
      }
   },
   "key2":{
      "key2A":{
         "someKey":"someValue"
      },
      "key2B":{
         "someKey":"someValue"
      }
   },         
   "key3":{
      "key3A":{
         "someKey":"someValue"
      },
      "key3B":{
         "someKey":"someValue"
      }
   }
} 
"@
$testJson = $testJson | ConvertFrom-Json

我们在$testJson中寻找Key1A,我们不知道它在父节点key1下,我们可以通过查看$testJson | gm的输出来做到这一点

$testJson | gm


   TypeName: System.Management.Automation.PSCustomObject

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
key1        NoteProperty System.Management.Automation.PSCustomObject key1=@{key1A=; key1B=}
key2        NoteProperty System.Management.Automation.PSCustomObject key2=@{key2A=; key2B=}
key3        NoteProperty System.Management.Automation.PSCustomObject key3=@{key3A=; key3B=}

我们可以在这里看到所有节点及其子节点都列在定义选项卡中,如果 JSON 更大,我们将无法看到整个定义选项卡,因此我们可以选择其中一个两件事:

$testJson | gm | select-object "Definition"
($testJson | gm).Definition

所以如果我们想找到Key1A 我们可以这样做

$testJson | gm | ? {$_.Definition -imatch "key1A"}

找到key1a所在位置的定义(不区分大小写,由-i而不是-c指定),它为我们提供了输出



   TypeName: System.Management.Automation.PSCustomObject

Name MemberType   Definition
---- ----------   ----------
key1 NoteProperty System.Management.Automation.PSCustomObject key1=@{key1A=; key1B=}

您可以看到父节点是key1,我们也可以使用它来获取它

($testJson | gm | ? {$_.Definition -imatch "key1A"}).name
key1

查看key1的内容我们可以做

$($testJson).$(($testJson | gm | ? {$_.Definition -imatch "key1A"}).name)

key1A                key1B
-----                -----
@{someKey=someValue} @{someKey=someValue}

还有key1a

$($testJson).$(($testJson | gm | ? {$_.Definition -imatch "key1A"}).name).key1a

someKey
-------
someValue

【讨论】:

    猜你喜欢
    • 2022-01-24
    • 2011-07-14
    • 1970-01-01
    • 2014-12-13
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多