[玩转系统] 在 PowerShell 中循环 JSON 文件 [2 种方法]
作者:精品下载站 日期:2024-12-14 05:31:36 浏览:13 分类:玩电脑
在 PowerShell 中循环 JSON 文件 [2 种方法]
使用 ConvertFrom-Json
Cmdlet
我们可以使用 ConvertFrom-Json
cmdlet 来遍历具有第一级和嵌套级键的 JSON 文件;下面让我们来探讨一下。
遍历包含一级键的JSON文件
使用 ConvertFrom-Json
和 foreach
循环来遍历仅具有第一级键的 JSON 文件。
file.json的内容:
{
"name": "John Christoper",
"age": 40,
"city": "Washington"
}
将 ConvertFrom-Json 与 foreach 循环结合使用:
$jsonData = Get-Content -Path "./file.json" -Raw | ConvertFrom-Json
foreach ($current_property in $jsonData.PSObject.Properties) {
Write-Host "$($current_property.Name): $($current_property.Value)"
}
输出 :
name: John Christoper
age: 40
city: Washington
我们使用 Get-Content
cmdlet 读取位于 ./file.json 路径(我们使用 -Path参数。
-Raw
参数确保在传递给 ConvertFrom-Json
cmdlet 之前将文件的全部内容作为单个字符串读取。
我们使用 ConvertFrom-Json cmdlet 将 JSON 字符串转换为 PowerShell 对象 (PSObject
),并将其存储在 $jsonData
变量中。然后,我们使用 for
循环来迭代 $jsonData
中的所有属性。
我们如何检索所有属性?此表达式 $json.PSObject.Properties
以集合形式检索 $jsonData
对象的属性。
对于每个属性 ($current_property
),我们使用 $current_property.Name
和 $current_property.Value
来检索当前属性名称及其对应的值, 分别。
之后,我们通过将属性名称及其值组合为 "$ ($current_property.Name): $ ($current_property.Value)"
来构造一个字符串,以进一步在 PowerShell 上显示使用 Write-Host
cmdlet 的控制台。
我们再举一个例子,不过这次我们会从用户那里获取密钥;请参见以下示例。
file.json的内容:
{
"name": "John Christoper",
"age": 40,
"city": "Washington"
}
将 ConvertFrom-Json 与 foreach 循环结合使用:
$jsonData = Get-Content -Path "./file.json" -Raw | ConvertFrom-Json
$key = Read-Host -Prompt "Enter key"
foreach ($record in $jsonData) {
if ($record |
Select-Object -ExpandProperty $key -ErrorAction SilentlyContinue){
Write-Host "$($record.$key)"
}else{
Write-Host "The given key was not found."
}
}
输出:第一次运行:
Enter key: name
John Christopher
输出:第一次运行:
Enter key: random
The given key was not found.
同样,我们使用 Get-Content
和 ConvertFrom-Json
读取 JSON 文件的内容并将其分配给 $jsonData
变量。之后,我们使用带有 -Prompt
参数的 Read-Host
cmdlet 来提示用户并输入所需的密钥。我们将此密钥存储在 $key
变量中。
接下来,我们使用 foreach
循环(又名 foreach
语句)来迭代 $jsonData
。在每次迭代中,我们使用 -ExpandProperty
参数将 $record
通过管道传输到 Select-Object cmdlet,以选择并展开 $key
给定的属性。代码>.
我们将 -ErrorAction
设置为 SilentlyContinue
以抑制错误消息,因为我们想要显示自定义消息而不是 PowerShell 生成的错误。
因此,如果 JSON 文件中存在 $key
,则将执行 if
块中的 Write-Host
cmdlet 以打印相应的价值;否则,将执行 else
块以在控制台上显示一条消息,指出未找到给定的已知内容。
让我们更深入地研究并使用带有嵌套键的 JSON 文件。
遍历包含一级键的JSON文件
使用 ConvertFrom-Json
和 foreach
循环来遍历具有嵌套键的 JSON 文件。
file.json的内容:
{
"student1": {
"name": {
"firstName": "John",
"lastName": "Doe"
},
"age": 30,
"Courses": {
"CS123": "Introduction to Computer Science",
"DS234": "Introduction to DataScience"
}
},
"student2": {
"name": {
"firstName": "Thomas",
"lastName": "Nelsan"
},
"age": 28,
"Courses": {
"CS123": "Java Programming",
"Ph234": "Introduction to Psychology"
}
}
}
将 ConvertFrom-Json 与 ForEach 结合使用:
#Define a function named TraverseJson that takes a JSON object ($json)
#and an optional prefix ($prefix)
function TraverseJson($json, $prefix = '') {
# Iterate over each property in the JSON object
foreach ($property in $json.PSObject.Properties) {
# Get the name and value of the property
$propertyName = $property.Name
$propertyValue = $property.Value
# Check if the property value is a nested object
if ($propertyValue -is [System.Management.Automation.PSCustomObject]) {
# Check if it's the first level of keys
if ($prefix -eq '') {
# Display the available first-level keys
Write-Host "First level keys:"
foreach ($firstLevelKey in $json.PSObject.Properties.Name) {
Write-Host "- $firstLevelKey"
}
# Prompt the user to choose a first-level key
$firstLevelKey = Read-Host "Choose a first level key (enter 'exit' to exit)"
# If 'exit' is entered, return and exit the recursion
if ($firstLevelKey -eq "exit") {
return
}
# If the chosen first-level key is valid
elseif ($json.PSObject.Properties.Name -contains $firstLevelKey) {
# Get the available second-level keys for the chosen first-level key
$secondLevelKeys = $json.$firstLevelKey.PSObject.Properties.Name
Write-Host "Second level keys under '$firstLevelKey':"
foreach ($secondLevelKey in $secondLevelKeys) {
Write-Host "- $secondLevelKey"
}
# Prompt the user to choose a second-level key
$secondLevelKey = Read-Host "Choose a second level key (enter 'exit' to exit)"
# If 'exit' is entered, return and exit the recursion
if ($secondLevelKey -eq "exit") {
return
}
# If the chosen second-level key is valid
elseif ($secondLevelKeys -contains $secondLevelKey) {
# Get the nested value corresponding to the chosen keys
$nestedValue = $json.$firstLevelKey.$secondLevelKey
Write-Host "Value of '$firstLevelKey.$secondLevelKey': $nestedValue"
}
else {
Write-Host "Invalid second level key. Please try again."
}
# Recursively call the TraverseJson function with the
#nested value and an updated prefix
TraverseJson $json.$firstLevelKey.$secondLevelKey ($firstLevelKey + '.' + $secondLevelKey + '.')
}
else {
Write-Host "Invalid first level key. Please try again."
}
# Return to exit the recursion
return
}
# If it's not the first level of keys
else {
# Recursively call the TraverseJson function with the
#nested object and an updated prefix
TraverseJson $propertyValue ($prefix + $propertyName + '.')
}
}
# If the property value is an ArrayList
elseif ($propertyValue -is [System.Collections.ArrayList]) {
# Iterate over each item in the ArrayList
$index = 0
foreach ($item in $propertyValue) {
#Recursively call the TraverseJson function with the item
#and an updated prefix, including the array index
TraverseJson $item ($prefix + $propertyName + "[$index].")
$index++
}
}
# If it's a regular property (not a nested object or ArrayList)
else {
# Display the key and value
Write-Host "${prefix}${propertyName}: ${propertyValue}"
}
}
}
#Read the content of the JSON file and convert it to a JSON object
$json = Get-Content -Path "./file.json" -Raw | ConvertFrom-Json
#Call the TraverseJson function with the JSON object
TraverseJson $json
输出:第一次运行:
First level keys:
- student1
- student2
Choose a first level key from the options above (or enter 'exit' to exit): student1
Second level keys under 'student1':
- name
- age
- Courses
Choose a second level key from the options above (or enter 'exit' to exit): age
Value of 'student1.age': 30
输出:第二次运行:
First level keys:
- student1
- student2
Choose a first level key from the options above (or enter 'exit' to exit): student2
Second level keys under 'student2':
- name
- age
- Courses
Choose a second level key from the options above (or enter 'exit' to exit): Courses
Value of 'student2.Courses': @{CS123=Java Programming; Ph234=Introduction to Psychology}
student2.Courses.CS123: Java Programming
student2.Courses.Ph234: Introduction to Psychology
不要害怕查看代码;它非常简单明了;下面我们一步步来学习一下:
- 首先,我们定义了
TraverseJson
函数,它有两个参数:$json
表示 JSON 对象,$prefiex
存储嵌套键的前缀。该函数递归遍历 JSON 对象并显示键值对。 TraverseJson
函数以foreach
循环开始,该循环使用$json.PSObject.Properties 迭代
。$json
对象的属性- 在
foreach
循环内,每个属性的名称和值分别分配给$propertyName
和$propertyValue
变量。 - 然后,上述代码使用
-is
运算符和类型[System.Management.Automation.PSCustomObject].如果是,则代码进入
if
块。 - 对
if
块中的$prefix
变量进行了额外检查。如果它是空字符串,我们就处于键的第一级。在本例中,代码通过迭代$json.PSObject.Properties.Name
来显示可用的一级密钥,并提示用户选择一级密钥。 - 如果用户输入
exit
,则函数返回并退出递归。否则,如果所选第一级密钥有效 ($json.PSObject.Properties.Name -contains $firstLevelKey
),则代码会显示所选第一级密钥的可用第二级密钥。 - 二级密钥从
$json.$firstLevelKey.PSObject.Properties.Name
获取并显示给用户。 - 系统会提示用户选择二级密钥。如果输入
exit
,则函数返回并退出递归。如果所选的二级键有效 ($secondLevelKeys -contains $secondLevelKey
),则代码使用$json.$firstLevelKey.$secondLevelKey
检索相应的嵌套值并显示它。 - 如果选择的二级密钥无效,则会显示错误消息,并提示用户重试。
- 最后,
TraverseJson
函数使用选定的嵌套值 ($json.$firstLevelKey.$secondLevelKey
) 和更新的前缀 ($firstLevelKey + '. ' + $secondLevelKey + '.'
)。 - 如果
$prefix
不为空(表示嵌套键),该函数会在嵌套对象 ($propertyValue
) 上递归调用TraverseJson
,并更新前缀($prefix + $propertyName + '.'
)。 - 如果
$propertyValue
是 ArrayList,则代码会进入elseif
块并使用foreach
循环迭代 ArrayList 中的每个项目。它使用包含数组索引的更新前缀对每个项目递归调用TraverseJson
。 - 如果
$propertyValue
既不是嵌套对象也不是 ArrayList,它会进入else
块并使用Write- 显示完整的键路径以及相应的值。主机 cmdlet。
- 最后,在函数外部,代码使用
Get-Content
cmdlet 读取 JSON 文件内容,使用ConvertFrom-Json
将其转换为 JSON 对象,并调用TraverseJson
函数与 JSON 对象。
因此,上面的代码允许用户交互地遍历 JSON 对象,选择不同级别的键,并查看其对应的值。此代码仅限于二级密钥;您可以为其添加价值以满足您的要求。
使用 ConvertFrom-Json
的重要性是什么?它迫使我们在上述每个解决方案中都使用它?由于 PowerShell 无法直接迭代 JSON 对象,因此我们使用 ConvertFrom-Json
将 JSON 字符串转换为 PSCustomObject,其中每个属性代表一个 JSON 字段。
如果您使用 PowerShell 3.0+ 版本,上述解决方案将有效;运行 $PSVersionTable.PSVersion
来检查您的 PowerShell 版本。如果您使用 PowerShell 版本 2.0 或正在寻找替代方案,以下解决方案适合您。
使用 JavaScriptSerializer 类
如果您使用的是 PowerShell 2.0 版,请使用 JavaScriptSerializer
类循环遍历 JSON。
使用 JavaScriptSerializer 类:
Add-Type -AssemblyName System.Web.Extensions
$JS = New-Object System.Web.Script.Serialization.JavaScriptSerializer
$json = @'
[{"id":1,"firstName":"John","lastName":"Doe","age":32},
{"id":2,"firstName":"Thomas","lastName":"Christoper","age":30},{"id":3,"firstName":"Johny","lastName":"Daniel","age":29}]
'@
$data = $JS.DeserializeObject($json)
$data.GetEnumerator() | foreach-Object {
foreach ($key in $_.Keys){
Write-Host "$key : $($_[$key])"
}
}
输出 :
id : 1
firstName : John
lastName : Doe
age : 32
id : 2
firstName : Thomas
lastName : Christoper
age : 30
id : 3
firstName : Johny
lastName : Daniel
age : 29
首先,我们使用 Add-Type 命令将 System.Web.Extensions 程序集加载到当前会话中。该程序集提供了用于在 .NET 应用程序中处理 JSON 数据的类。
然后,我们使用 New-Object cmdlet 从 System.Web.Script.Serialization 命名空间创建 JavaScriptSerializer 类的对象,并将其存储在 $JS 变量。
之后,我们使用了 $JS
对象的 DeserializeObject()
方法。该方法将 JSON 字符串 ($json
) 作为参数,将其反序列化为 PowerShell 对象。我们将结果对象存储在 $data
变量中。
接下来,我们使用 GetEnumerator()
方法和 foreach-Object
cmdlet 循环访问 $data
中的每个项目。在 foreach-Object
内部,我们使用 foreach
循环与当前项的 Keys
属性来迭代当前项中的每个键。我们使用 Write-Host
cmdlet 显示相应的键值对。
这就是如何在 PowerShell 中循环 JSON 文件的全部内容。
猜你还喜欢
- 03-30 [玩转系统] 如何用批处理实现关机,注销,重启和锁定计算机
- 02-14 [系统故障] Win10下报错:该文件没有与之关联的应用来执行该操作
- 01-07 [系统问题] Win10--解决锁屏后会断网的问题
- 01-02 [系统技巧] Windows系统如何关闭防火墙保姆式教程,超详细
- 12-15 [玩转系统] 如何在 Windows 10 和 11 上允许多个 RDP 会话
- 12-15 [玩转系统] 查找 Exchange/Microsoft 365 中不活动(未使用)的通讯组列表
- 12-15 [玩转系统] 如何在 Windows 上安装远程服务器管理工具 (RSAT)
- 12-15 [玩转系统] 如何在 Windows 上重置组策略设置
- 12-15 [玩转系统] 如何获取计算机上的本地管理员列表?
- 12-15 [玩转系统] 在 Visual Studio Code 中连接到 MS SQL Server 数据库
- 12-15 [玩转系统] 如何降级 Windows Server 版本或许可证
- 12-15 [玩转系统] 如何允许非管理员用户在 Windows 中启动/停止服务
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[影视] 黑道中人 Alto Knights(2025)剧情 犯罪 历史 电影
[古装剧] [七侠五义][全75集][WEB-MP4/76G][国语无字][1080P][焦恩俊经典]
[实用软件] 虚拟手机号 电话 验证码 注册
[电视剧] 安眠书店/你 第五季 You Season 5 (2025) 【全10集】
[电视剧] 棋士(2025) 4K 1080P【全22集】悬疑 犯罪 王宝强 陈明昊
[软件合集] 25年6月5日 精选软件22个
[软件合集] 25年6月4日 精选软件36个
[短剧] 2025年06月04日 精选+付费短剧推荐33部
[短剧] 2025年06月03日 精选+付费短剧推荐25部
[软件合集] 25年6月3日 精选软件44个
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电视剧] 欢乐颂.5部全 (2016-2024)
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[影视] 【稀有资源】香港老片 艺坛照妖镜之96应召名册 (1996)
[剧集] 神经风云(2023)(完结).4K
[剧集] [BT] [TVB] [黑夜彩虹(2003)] [全21集] [粤语中字] [TV-RMVB]
[实用软件] 虚拟手机号 电话 验证码 注册
[资源] B站充电视频合集,包含多位重量级up主,全是大佬真金白银买来的~【99GB】
[影视] 内地绝版高清录像带 [mpg]
[书籍] 古今奇书禁书三教九流资料大合集 猎奇必备珍藏资源PDF版 1.14G
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电影] 美国队长4 4K原盘REMUX 杜比视界 内封简繁英双语字幕 49G
[电影] 死神来了(1-6)大合集!
[软件合集] 25年05月13日 精选软件16个
[精品软件] 25年05月15日 精选软件18个
[绝版资源] 南与北 第1-2季 合集 North and South (1985) /美国/豆瓣: 8.8[1080P][中文字幕]
[软件] 25年05月14日 精选软件57个
[短剧] 2025年05月14日 精选+付费短剧推荐39部
[短剧] 2025年05月15日 精选+付费短剧推荐36部
- 最新评论
-
- 热门tag