about_Hash_Tables
简短说明
介绍如何在 PowerShell 中创建、使用和排序哈希表。
长说明
哈希表也称为字典或关联数组,是存储一个或多个键/值对的紧凑数据结构。 例如,哈希表可能包含一系列 IP 地址和计算机名称,其中 IP 地址是键,计算机名称是值,反之亦然。
在 PowerShell 中,每个哈希表都是一个 Hashtable (System.Collections.Hashtable) 对象。 可以在 PowerShell 中使用 Hashtable 对象的属性和方法。
从 PowerShell 3.0 开始,可以使用 [有序] 属性在 PowerShell 中 (System.Collections.Specialized.OrderedDictionary) 创建有序字典。
有序字典与哈希表的不同之处在于,键始终按列出顺序显示。 哈希表中键的顺序未确定。
哈希表中的键和值也是 .NET 对象。 它们通常是字符串或整数,但它们可以具有任何对象类型。 还可以创建嵌套哈希表,其中键的值是另一个哈希表。
经常使用哈希表,因为它们对于查找和检索数据非常高效。 可以使用哈希表在 PowerShell 中存储列表和创建计算属性。 PowerShell 还有一个 cmdlet, ConvertFrom-StringData
用于将字符串转换为哈希表。
语法
哈希表的语法如下所示:
@{ <name> = <value>; [<name> = <value> ] ...}
有序字典的语法如下所示:
[ordered]@{ <name> = <value>; [<name> = <value> ] ...}
[有序] 属性是在 PowerShell 3.0 中引入的。
创建哈希表
若要创建哈希表,请遵循以下准则:
- 使用 at 符号 ()
@
开始哈希表。 - 将哈希表括在大括号 (
{}
) 。 - 为哈希表的内容输入一个或多个键/值对。
- 使用等号 (
=
) 将每个键与其值分开。 - 使用分号 (
;
) 或换行符分隔键/值对。 - 包含空格的键必须用引号引起来。 值必须是有效的 PowerShell 表达式。 字符串必须出现在引号中,即使它们不包含空格。
- 若要管理哈希表,请将其保存在变量中。
- 将有序哈希表分配给变量时,请将 [有序] 属性放在符号之前
@
。 如果将它放在变量名称之前,则命令将失败。
若要在 $hash 的值中创建空哈希表,请键入:
$hash = @{}
还可以在创建哈希表时向其添加键和值。 例如,以下语句创建一个包含三个键的哈希表。
$hash = @{ Number = 1; Shape = "Square"; Color = "Blue"}
创建有序字典
可以通过添加 OrderedDictionary 类型的对象来创建有序字典,但创建有序字典的最简单方法是使用 [ordered]
特性。
特性 [ordered]
在 PowerShell 3.0 中引入。
将 属性放在“@”符号之前。
$hash = [ordered]@{ Number = 1; Shape = "Square"; Color = "Blue"}
可以使用与使用哈希表相同的方式使用有序字典。 任一类型都可以用作采用哈希表或字典 (iDictionary) 的参数的值。
不能使用 [ordered]
特性转换或强制转换哈希表。 如果将有序属性置于变量名称之前,则命令将失败并显示以下错误消息。
[ordered]$hash = @{}
ParserError:
Line |
1 | [ordered]$hash = @{}
| ~~~~~~~~~~~~~~
| The ordered attribute can be specified only on a hash literal node.
若要更正表达式,请移动 [有序] 属性。
$hash = [ordered]@{}
可以将有序字典强制转换为哈希表,但即使清除变量并输入新值,也无法恢复有序属性。 若要重新建立顺序,必须删除并重新创建变量。
[hashtable]$hash = [ordered]@{
Number = 1; Shape = "Square"; Color = "Blue"}
$hash
Name Value
---- -----
Color Blue
Shape Square
Number 1
显示哈希表
若要显示保存在变量中的哈希表,请键入变量名称。 默认情况下,哈希表显示为一个表,其中一列用于键,一个列用于值。
$hash
Name Value
---- -----
Shape Square
Color Blue
Number 1
哈希表具有 Keys 和 Values 属性。 使用点表示法显示所有键或所有值。
$hash.keys
Number
Shape
Color
$hash.values
1
Square
Blue
每个键名称也是哈希表的一个属性,其值是 key-name 属性的值。 使用以下格式显示属性值。
$hashtable.<key>
<value>
例如:
$hash.Number
1
$hash.Color
Blue
如果键名称与 HashTable 类型的某个属性名称冲突,则可以使用 PSBase
访问这些属性。 例如,如果密钥名称为 keys
并且要返回 Keys 的集合,请使用以下语法:
$hashtable.PSBase.Keys
哈希表具有 Count 属性,指示哈希表中键值对的数目。
$hash.count
3
哈希表不是数组,因此不能将整数用作哈希表中的索引,但可以使用键名称为哈希表编制索引。 如果键是字符串值,请将密钥名称括在引号中。
例如:
$hash["Number"]
1
添加和删除键和值
若要向哈希表添加键和值,请使用以下命令格式。
$hash["<key>"] = "<value>"
例如,若要将值为“Now”的“Time”键添加到哈希表,请使用以下语句格式。
$hash["Time"] = "Now"
还可以使用 System.Collections.Hashtable 对象的 Add 方法向哈希表添加键和值。 Add 方法具有以下语法:
Add(Key, Value)
例如,若要将值为“Now”的“Time”键添加到哈希表,请使用以下语句格式。
$hash.Add("Time", "Now")
此外,还可以使用加法运算符 (+
) 向现有哈希表添加哈希表,从而将键和值添加到哈希表。 例如,以下语句将值为“Now”的“Time”键添加到$hash变量中的哈希表中。
$hash = $hash + @{Time="Now"}
还可以添加存储在变量中的值。
$t = "Today"
$now = (Get-Date)
$hash.Add($t, $now)
不能使用减法运算符从哈希表中删除键/值对,但可以使用 Hashtable 对象的 Remove 方法。 Remove 方法将键作为其值。
Remove 方法具有以下语法:
Remove(Key)
例如,若要从$hash变量的值的哈希表中删除 Time=Now 键/值对,请键入:
$hash.Remove("Time")
可以在 PowerShell 中使用 Hashtable 对象的所有属性和方法,包括 Contains、Clear、Clone 和 CopyTo。 有关 Hashtable 对象的详细信息,请参阅 System.Collections.Hashtable。
HashTable 中的对象类型
哈希表中的键和值可以具有任何 .NET 对象类型,单个哈希表可以具有多个类型的键和值。
以下语句创建进程名称字符串和处理对象值的哈希表,并将其保存在 变量中 $p
。
$p = @{"PowerShell" = (Get-Process PowerShell);
"Notepad" = (Get-Process notepad)}
可以在 中 $p
显示哈希表,并使用键名称属性来显示值。
$p
Name Value
---- -----
PowerShell System.Diagnostics.Process (PowerShell)
Notepad System.Diagnostics.Process (notepad)
$p.PowerShell
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
441 24 54196 54012 571 5.10 1788 PowerShell
$p.keys | foreach {$p.$_.handles}
441
251
哈希表中的键也可以是任何 .NET 类型。 以下语句将键/值对添加到 变量中的 $p
哈希表。 键是一个 Service 对象,表示 WinRM 服务,值是服务的当前状态。
$p = $p + @{(Get-Service WinRM) = ((Get-Service WinRM).Status)}
可以使用与哈希表中其他对相同的方法来显示和访问新的键/值对。
$p
Name Value
---- -----
PowerShell System.Diagnostics.Process (PowerShell)
Notepad System.Diagnostics.Process (notepad)
System.ServiceProcess.Servi... Running
$p.keys
PowerShell
Notepad
Status Name DisplayName
------ ---- -----------
Running winrm Windows Remote Management (WS-Manag...
$p.keys | foreach {$_.name}
winrm
哈希表中的键和值也可以是 Hashtable 对象。 以下语句将键/值对添加到变量中的 $p
哈希表,其中键是字符串 Hash2,值是包含三个键/值对的哈希表。
$p = $p + @{"Hash2"= @{a=1; b=2; c=3}}
可以使用相同方法显示和访问新值。
$p
Name Value
---- -----
PowerShell System.Diagnostics.Process (PowerShell)
Notepad System.Diagnostics.Process (notepad)
System.ServiceProcess.Servi... Running
Hash2 {a, b, c}
$p.Hash2
Name Value
---- -----
a 1
b 2
c 3
$p.Hash2.b
2
对键和值进行排序
哈希表中的项本质上是无序的。 每次显示键/值对时,它们可能以不同的顺序显示。
尽管无法对哈希表进行排序,但可以使用哈希表的 GetEnumerator 方法来枚举键和值,然后使用 Sort-Object cmdlet 对枚举值进行排序以便显示。
例如,以下命令枚举变量哈希表中的键和值, $p
然后按字母顺序对键进行排序。
$p.GetEnumerator() | Sort-Object -Property key
Name Value
---- -----
Notepad System.Diagnostics.Process (notepad)
PowerShell System.Diagnostics.Process (PowerShell)
System.ServiceProcess.Servi... Running
以下命令使用相同的过程按降序对哈希值进行排序。
$p.getenumerator() | Sort-Object -Property Value -Descending
Name Value
---- -----
PowerShell System.Diagnostics.Process (PowerShell)
Notepad System.Diagnostics.Process (notepad)
System.ServiceProcess.Servi... Running
从哈希表创建对象
从 PowerShell 3.0 开始,可以从属性和属性值的哈希表创建对象。
语法如下所示:
[<class-name>]@{
<property-name>=<property-value>
<property-name>=<property-value>
}
此方法仅适用于具有 null 构造函数(即,没有参数的构造函数)的类。 对象属性必须是公共且可设置的。
有关详细信息,请参阅 about_Object_Creation。
ConvertFrom-StringData
cmdlet ConvertFrom-StringData
将字符串或键/值对的 here 字符串转换为哈希表。 可以在脚本的 ConvertFrom-StringData
“数据”部分安全地使用该 cmdlet,并且可以将其与 cmdlet 一起使用 Import-LocalizedData
,在用户界面 (UI) 当前用户的区域性中显示用户消息。
当哈希表中的值包含引号时,Here-string 特别有用。 有关 here-strings 的详细信息,请参阅 about_Quoting_Rules。
以下示例演示如何在上一示例中创建用户消息的 here 字符串,以及如何使用 ConvertFrom-StringData
将其从字符串转换为哈希表。
以下命令创建键/值对的 here 字符串,然后将其保存在 变量中 $string
。
$string = @"
Msg1 = Type "Windows".
Msg2 = She said, "Hello, World."
Msg3 = Enter an alias (or "nickname").
"@
此命令使用 ConvertFrom-StringData
cmdlet 将 here 字符串转换为哈希表。
ConvertFrom-StringData $string
Name Value
---- -----
Msg3 Enter an alias (or "nickname").
Msg2 She said, "Hello, World."
Msg1 Type "Windows".
有关 here-strings 的详细信息,请参阅 about_Quoting_Rules。