about_Hash_Tables
Descrição breve
Descreve como criar, usar e classificar tabelas de hash no PowerShell.
Descrição longa
Um hashtable, também conhecido como dicionário ou matriz associativa, é uma estrutura de dados compacta que armazena um ou mais pares de valores-chave. Por exemplo, uma tabela de hash pode conter uma série de endereços IP e nomes de computador, em que os endereços IP são as chaves e os nomes de computador são os valores, ou vice-versa.
No PowerShell, cada um hashtable é um [System.Collections.Hashtable]
objeto. Você pode usar as propriedades e os métodos de Hashtable objetos no PowerShell.
A partir do PowerShell 3.0, você pode usar o [ordered]
acelerador de tipo para criar um [System.Collections.Specialized.OrderedDictionary]
objeto no PowerShell.
Os dicionários ordenados diferem das tabelas de hash, pois as chaves sempre aparecem na ordem em que você as lista. A ordem das chaves em a hashtable não é determinística.
As chaves e o valor nas tabelas de hash também são objetos .NET. Na maioria das vezes, são cadeias de caracteres ou inteiros, mas podem ter qualquer tipo de objeto. Você também pode criar tabelas de hash aninhadas, nas quais o valor de uma chave é outro hashtable.
As tabelas de hash são usadas com frequência porque são eficientes para localizar e recuperar dados. Você pode usar tabelas de hash para armazenar listas e criar propriedades calculadas no PowerShell. E o cmdlet converte ConvertFrom-StringData
dados de cadeia de caracteres estruturados em um hashtable.
Sintaxe
A sintaxe de a hashtable é a seguinte:
@{ <name> = <value>; [<name> = <value> ] ...}
A sintaxe de um dicionário ordenado é a seguinte:
[ordered]@{ <name> = <value>; [<name> = <value> ] ...}
O [ordered]
acelerador de tipo foi introduzido no PowerShell 3.0.
Para criar um hashtable, siga estas diretrizes:
- Comece com um sinal de arroba hashtable (
@
). - Coloque as hashtable chaves
{}
(). - Insira um ou mais pares de valores-chave para o conteúdo do hashtable.
- Use um sinal de igual (
=
) para separar cada chave de seu valor. - Use um ponto-e-vírgula (
;
) ou uma quebra de linha para separar os pares de valores-chave. - As chaves que contêm espaços devem ser colocadas entre aspas. Os valores devem ser expressões válidas do PowerShell. As cadeias de caracteres devem aparecer entre aspas, mesmo que não incluam espaços.
- Para gerenciar o hashtable, salve-o em uma variável.
- Ao atribuir uma ordenação hashtable a uma variável, coloque o
[ordered]
tipo antes do@
símbolo. Se você colocá-lo antes do nome da variável, o comando falhará.
Você pode usar dicionários ordenados da mesma forma que usa tabelas de hash. Qualquer tipo pode ser usado como o valor de parâmetros que usam objetos do tipo um hashtable ou dicionário (iDictionary).
Criando tabelas de hash e dicionários ordenados
Considere os seguintes hashtable exemplos de dicionário ordenado:
$hash = @{
1 = 'one'
2 = 'two'
'three' = 3
}
$hash
Name Value
---- -----
three 3
2 two
1 one
Como você pode ver, os pares de chave-valor em a hashtable não são apresentados na ordem em que foram definidos.
A maneira mais fácil de criar um dicionário ordenado é usar o [ordered]
atributo. Coloque o atributo imediatamente antes do @
símbolo.
$dictionary = [ordered]@{
1 = 'one'
2 = 'two'
'three' = 3
}
$dictionary
Name Value
---- -----
1 one
2 two
three 3
Ao contrário das tabelas de hash, os dicionários ordenados mantêm a ordem do valor-chave.
Convertendo tabelas de hash e dicionários ordenados
Você não pode usar o [ordered]
acelerador de tipo para converter ou converter um hashtablearquivo .
Se você colocar o atributo ordenado antes do nome da variável, o comando falhará com a seguinte mensagem de erro.
[ordered]$orderedhash = @{}
ParserError:
Line |
1 | [ordered]$orderedhash = @{}
| ~~~~~~~~~~~~~~
| The ordered attribute can be specified only on a hash literal node.
Para corrigir a expressão, mova o atributo [ordered].
$orderedhash = [ordered]@{}
Você pode converter um dicionário ordenado em um hashtable, mas não pode garantir a ordem dos membros.
[hashtable]$newhash = [ordered]@{
Number = 1
Shape = "Square"
Color = "Blue"
}
$newhash
Name Value
---- -----
Color Blue
Shape Square
Number 1
Hashtable e propriedades do dicionário
Tabelas de hash e dicionários ordenados compartilham várias propriedades. Considere as $hash
variáveis e $dictionary
definidas nos exemplos anteriores.
$hash | Get-Member -MemberType Properties, ParameterizedProperty
TypeName: System.Collections.Hashtable
Name MemberType Definition
---- ---------- ----------
Item ParameterizedProperty System.Object Item(System.Object key) {get;set;}
Count Property int Count {get;}
IsFixedSize Property bool IsFixedSize {get;}
IsReadOnly Property bool IsReadOnly {get;}
IsSynchronized Property bool IsSynchronized {get;}
Keys Property System.Collections.ICollection Keys {get;}
SyncRoot Property System.Object SyncRoot {get;}
Values Property System.Collections.ICollection Values {get;}
$dictionary | Get-Member -MemberType Properties, ParameterizedProperty
TypeName: System.Collections.Specialized.OrderedDictionary
Name MemberType Definition
---- ---------- ----------
Item ParameterizedProperty System.Object Item(int index) {get;set;},
System.Object Item(System.Object key) {get;set;}
Count Property int Count {get;}
IsFixedSize Property bool IsFixedSize {get;}
IsReadOnly Property bool IsReadOnly {get;}
IsSynchronized Property bool IsSynchronized {get;}
Keys Property System.Collections.ICollection Keys {get;}
SyncRoot Property System.Object SyncRoot {get;}
Values Property System.Collections.ICollection Values {get;}
As propriedades mais usadas são Count, Keys, Values e Item.
A propriedade Count que indica o número de pares de chave-valor no objeto.
A propriedade Keys é uma coleção dos nomes de chave no hashtable dicionário or.
PS> $hash.Keys three 2 1 PS> $dictionary.Keys 1 2 three
A propriedade Values é uma coleção dos valores no hashtable dicionário or.
PS> $hash.Values 3 two one PS> $dictionary.Values one two 3
A propriedade Item é uma propriedade parametrizada que retorna o valor do item especificado. As tabelas de hash usam a chave como parâmetro para a propriedade parametrizada, enquanto os dicionários usam o índice por padrão. Essa diferença afeta como você acessa os valores de cada tipo.
Acessando valores
Há duas maneiras comuns de acessar os valores em um hashtable dicionário or: notação de membro ou notação de índice de matriz.
Notação de membro - Os valores podem ser acessados usando o nome da chave como uma propriedade de membro do objeto. Por exemplo:
PS> $hash.1 one PS> $dictionary.2 two
Notação de índice de matriz - Os valores podem ser acessados usando a notação de índice. O PowerShell converte essa notação em uma chamada para a propriedade parametrizada Item do objeto.
Quando você usa a notação de índice com tabelas de hash, o valor dentro dos colchetes é o nome da chave. Se a chave for um valor de cadeia de caracteres, coloque o nome da chave entre aspas. Por exemplo:
PS> $hash['three'] 3 PS> $hash[2] 2
Neste exemplo, o valor
2
da chave não é um índice na coleção de valores. É o valor da chave no par chave-valor. Você pode provar isso indexando na coleção de valores.PS> ([array]$hash.Values)[2] one
Quando você usa a notação de índice com dicionários, o valor dentro dos colchetes é interpretado com base em seu tipo. Se o valor for um inteiro, ele será tratado como um índice na coleção de valores. Se o valor não for um número inteiro, ele será tratado como o nome da chave. Por exemplo:
PS> $dictionary[1] two PS> ([array]$dictionary.Values)[1] two PS> $dictionary[[object]1] one PS> $dictionary['three'] 3
Neste exemplo, o valor
[1]
da matriz é um índice na coleção de valores usando aItem(int index)
sobrecarga de propriedade parametrizada. O valor[[object]1]
da matriz não é um índice, mas um valor de chave usando aItem(System.Object key)
sobrecarga.Observação
Esse comportamento pode ser confuso quando o valor da chave é um número inteiro. Quando possível, você deve evitar o uso de valores de chave inteiros em dicionários.
Manipulando colisões de nome de propriedade
Se o nome da chave colidir com um dos nomes de propriedade do HashTable tipo, você poderá usar o membro intrínseco psbase para acessar essas propriedades. Por exemplo, se o nome da chave for keys
e você quiser retornar a coleção das HashTable chaves, use esta sintaxe:
$hashtable.psbase.Keys
Esse requisito se aplica a outros tipos que implementam a System.Collections.IDictionary interface, como OrderedDictionaryo .
Iterando sobre chaves e valores
Você pode iterar sobre as chaves em um hashtable para processar os valores de várias maneiras. Cada um dos exemplos nesta seção tem saída idêntica. Eles repetem sobre a $hash
variável definida aqui:
$hash = [ordered]@{ Number = 1; Shape = "Square"; Color = "Blue"}
Observação
Nesses exemplos, $hash
é definido como um dicionário ordenado para garantir que a saída esteja sempre na mesma ordem. Esses exemplos funcionam da mesma forma para tabelas de hash padrão, mas a ordem da saída não é previsível.
Cada exemplo retorna uma mensagem para cada chave e seu valor:
The value of 'Number' is: 1
The value of 'Shape' is: Square
The value of 'Color' is: Blue
Este exemplo usa um foreach
bloco para iterar sobre as chaves.
foreach ($Key in $hash.Keys) {
"The value of '$Key' is: $($hash[$Key])"
}
Este exemplo usa ForEach-Object
para iterar sobre as chaves.
$hash.Keys | ForEach-Object {
"The value of '$_' is: $($hash[$_])"
}
Este exemplo usa o GetEnumerator()
método para enviar cada par de chave-valor por meio do pipeline para ForEach-Object
.
$hash.GetEnumerator() | ForEach-Object {
"The value of '$($_.Key)' is: $($_.Value)"
}
Este exemplo usa os GetEnumerator()
métodos and ForEach()
para iterar em cada par de chave-valor.
$hash.GetEnumerator().ForEach({"The value of '$($_.Key)' is: $($_.Value)"})
Adicionando e removendo chaves e valores
Normalmente, ao criar um hashtable , você inclui os pares de chave-valor na definição. No entanto, você pode adicionar e remover pares de chave-valor de a hashtable a qualquer momento. O exemplo a seguir cria um arquivo .hashtable
$hash = @{}
Você pode adicionar pares de valores-chave usando a notação de matriz. Por exemplo, o exemplo a seguir adiciona uma Time
chave com um valor de Now
ao hashtable.
$hash["Time"] = "Now"
Você também pode adicionar chaves e valores a um hashtable usando o Add()
System.Collections.Hashtable método do objeto. O Add()
método tem a seguinte sintaxe:
Add(Key, Value)
Por exemplo, para adicionar uma Time
chave com um valor de ao hashtable, use o formato de Now
instrução a seguir.
$hash.Add("Time", "Now")
E você pode adicionar chaves e valores a um hashtable usando o operador de adição (+
) para adicionar a hashtable a um .hashtable Por exemplo, a instrução a seguir adiciona uma Time
chave com um valor de Now
para o hashtable na $hash
variável.
$hash = $hash + @{Time="Now"}
Você também pode adicionar valores armazenados em variáveis.
$t = "Today"
$now = (Get-Date)
$hash.Add($t, $now)
Você não pode usar um operador de subtração para remover um par de valores-chave de uma tabela de hash, mas pode usar o Remove()
hashtable método do objeto. O Remove
método tem a seguinte sintaxe:
$object.Remove(<key>)
O exemplo a seguir remove o Time
par chave-valor do $hash
.
$hash.Remove("Time")
Tipos de objeto em HashTables
As chaves e os valores em um hashtable podem ter qualquer tipo de objeto .NET, e um único hashtable pode ter chaves e valores de vários tipos.
A instrução a seguir cria um hashtable de cadeias de caracteres de nome de processo e valores de objeto de processo e os salva na $p
variável.
$p = @{
"PowerShell" = (Get-Process PowerShell)
"Notepad" = (Get-Process notepad)
}
Você pode exibir o hashtable in $p
e usar as propriedades do nome da chave para exibir os valores.
PS> $p
Name Value
---- -----
PowerShell System.Diagnostics.Process (PowerShell)
Notepad System.Diagnostics.Process (notepad)
PS> $p.PowerShell
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
441 24 54196 54012 571 5.10 1788 PowerShell
PS> $p.keys | ForEach-Object {$p.$_.handles}
441
251
As chaves em um hashtable podem ser qualquer tipo .NET. A instrução a seguir adiciona um par chave-valor à hashtable variável na $p
variável. A chave é um objeto Service que representa o serviço WinRM e o valor é o status atual do serviço.
$p = $p + @{
(Get-Service WinRM) = ((Get-Service WinRM).Status)
}
Você pode exibir e acessar o novo par de valores-chave usando os mesmos métodos que você usa para outros pares no hashtable.
PS> $p
Name Value
---- -----
PowerShell System.Diagnostics.Process (PowerShell)
Notepad System.Diagnostics.Process (notepad)
System.ServiceProcess.Servi... Running
PS> $p.keys
PowerShell
Notepad
Status Name DisplayName
------ ---- -----------
Running winrm Windows Remote Management (WS-Manag...
PS> $p.keys | ForEach-Object {$_.name}
WinRM
As chaves e valores em a hashtable também podem ser Hashtable objetos. A instrução a seguir adiciona um hashtable par chave-valor à variável $p
na qual a chave é uma cadeia de caracteres, Hash2, e o valor é um hashtable com três pares de chave-valor.
$p = $p + @{
"Hash2"= @{a=1; b=2; c=3}
}
Você pode exibir e acessar os novos valores usando os mesmos métodos.
PS> $p
Name Value
---- -----
PowerShell System.Diagnostics.Process (pwsh)
Hash2 {[a, 1], [b, 2], [c, 3]}
Notepad System.Diagnostics.Process (Notepad)
WinRM Running
PS> $p.Hash2
Name Value
---- -----
a 1
b 2
c 3
PS> $p.Hash2.b
2
Ordenando chaves e valores
Os itens em a hashtable são intrinsecamente não ordenados. Os pares de chave-valor podem aparecer em uma ordem diferente cada vez que você os exibe.
Embora não seja possível classificar um hashtable, você pode usar o GetEnumerator()
método de tabelas de hash para enumerar as chaves e os valores e, em seguida, usar o Sort-Object
cmdlet para classificar os valores enumerados para exibição.
Por exemplo, os comandos a seguir enumeram as chaves e os valores na tabela de hash na variável e, em $p
seguida, classificam as chaves em ordem alfabética.
PS> $p.GetEnumerator() | Sort-Object -Property key
Name Value
---- -----
Hash2 {[a, 1], [b, 2], [c, 3]}
Notepad System.Diagnostics.Process (Notepad)
PowerShell System.Diagnostics.Process (pwsh)
WinRM Running
O comando a seguir usa o mesmo procedimento para classificar os valores de hash em ordem decrescente.
PS> $p.GetEnumerator() | Sort-Object -Property Value -Descending
Name Value
---- -----
PowerShell System.Diagnostics.Process (pwsh)
Notepad System.Diagnostics.Process (Notepad)
Hash2 {[a, 1], [b, 2], [c, 3]}
WinRM Running
Criando objetos a partir de tabelas de hash
A partir do PowerShell 3.0, você pode criar um objeto a partir de propriedades hashtable e valores de propriedade.
A sintaxe dela é a seguinte:
[<class-name>]@{
<property-name>=<property-value>
<property-name>=<property-value>
}
Esse método funciona apenas para classes que têm um construtor que não tem parâmetros. As propriedades do objeto devem ser públicas e configuráveis.
Para obter mais informações, consulte about_Object_Creation.
ConvertFrom-StringData
O ConvertFrom-StringData
cmdlet converte uma cadeia de caracteres ou uma cadeia de caracteres aqui de pares de chave-valor em um hashtable. Você pode usar o ConvertFrom-StringData
cmdlet com segurança na seção Dados de um script e pode usá-lo com o Import-LocalizedData
cmdlet para exibir mensagens do usuário na cultura da interface do usuário atual.
As cadeias de caracteres aqui são especialmente úteis quando os valores incluem hashtable aspas. Para obter mais informações sobre here-strings, consulte about_Quoting_Rules.
O exemplo a seguir mostra como criar uma cadeia de caracteres here das mensagens do usuário no exemplo anterior e como usá-las ConvertFrom-StringData
para convertê-las de uma cadeia de caracteres em um hashtablearquivo .
O comando a seguir cria uma cadeia de caracteres aqui dos pares de valores-chave e a salva na $string
variável.
$string = @"
Msg1 = Type "Windows".
Msg2 = She said, "Hello, World."
Msg3 = Enter an alias (or "nickname").
"@
Esse comando usa o ConvertFrom-StringData
cmdlet para converter a cadeia de caracteres here em um hashtable.
ConvertFrom-StringData $string
Name Value
---- -----
Msg3 Enter an alias (or "nickname").
Msg2 She said, "Hello, World."
Msg1 Type "Windows".
Para obter mais informações sobre here-strings, consulte about_Quoting_Rules.