0

我在 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

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

4

3 回答 3

2

jq有一个递归下降 ..运算符,可以搜索所有键,如 xpath //

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

{
  "someKey1b": "someValue1b"
}
于 2020-06-23T19:23:57.517 回答
2
# 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"
于 2020-06-24T03:23:17.840 回答
1

您可以Key1A通过查看Get-Member.

让我们将您的 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

我们正在寻找我们不知道在父节点下的Key1A,我们可以通过查看输出来做到这一点$testJsonkey1$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"}

它找到了 where key1ais in 中的定义(不区分大小写,由-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
于 2020-06-23T19:27:51.283 回答