O que $ _ significa no PowerShell?

226

Eu já vi muitas coisas a seguir no PowerShell, mas o que isso faz exatamente?

$_
Micah
fonte
5
A questão, é claro, foi respondida para o single especial sinal dado, mas para um wallchart ilustrando tudo de tokens especiais do PowerShell, dar uma olhada em The Complete Guide to PowerShell Pontuação
Michael Sorens

Respostas:

171

Essa é a variável para o valor atual na linha de tubulação, chamada $PSItemno Powershell 3 e mais recente.

1,2,3 | %{ write-host $_ } 

ou

1,2,3 | %{ write-host $PSItem } 

Por exemplo, no código acima, o %{}bloco é chamado para todos os valores na matriz. A variável $_ou $PSItemconterá o valor atual.

JaredPar
fonte
42
Não está necessariamente relacionado ao pipeline. É mais um "argumento atual para o bloco de scripts em execução no momento". Por exemplo, enquanto você pode usá-lo perfeitamente ForEach-Objectou Where-Objectem algo como Get-Foo|Add-Member NoteProperty Bar ($_.SomeProperty)- há um pipeline envolvido, mas nenhum bloco de script e, portanto, não $_. (Dito isto, a ajuda PowerShell também se refere ao oleoduto para $_confuso..)
Joey
@ Joey, você pode usar absolutamente $ _ no seu exemplo. Get-Foo | Add-Member -Type NoteProperty -Name Bar -Value $_.SomeProperty
Xalorous 06/11
@Xalorous: Só porque não produz um erro, não significa que funciona: Get-ChildItem | Add-Member -Type NoteProperty -Name Bar -Value $_.Name -PassThru | Select Bar... Bem, pode funcionar se você tiver um $_escopo no qual está executando esse pipeline. Mas isso é muito diferente do que você costuma dizer quando tenta escrever algo assim.
Joey
@ Joey $_no que você escreveu é, por algum motivo, não percorrendo todos os objetos. Tente isso em vez disso. gci | % { $_ | add-member -Type NoteProperty -Name Bar -Value $_.name -PassThru } | Select Bar. Eu suspeito que ter gci | cmdletsem o foreach explícito está coletando resultados de gci e passando uma matriz para o cmdlet. No entanto, a matriz é um objeto, portanto, está adicionando uma propriedade ao objeto da matriz. A matriz não possui uma propriedade 'name'; portanto, o valor atribuído a $ _. Bar é $ null. A linha inferior é que $ _ é usado extensivamente com pipelining. Não é necessário que% {} faça o loop é novo.
Xalorous 23/11
Versão de trabalho com o pipeline extra removido. gci | % { add-member -InputObject $_ -Type NoteProperty -Name Bar -Value $_.name -PassThru } | Select Bar
Xalorous
37

Eu acho que a maneira mais fácil de pensar sobre essa variável como parâmetro de entrada na expressão lambda em c #. Ou seja, $_é semelhante ao xem x => Console.WriteLine(x)função anônima em C #. Considere os seguintes exemplos:

PowerShell:

1,2,3 | ForEach-Object {Write-Host $_}

Impressões:

1
2
3

ou

1,2,3 | Where-Object {$_ -gt 1}

Impressões:

2
3

E compare isso com a sintaxe C # usando o LINQ:

var list = new List<int> { 1, 2, 3 };
list.ForEach( _ => Console.WriteLine( _ ));

Impressões:

1
2
3

ou

list.Where( _ => _ > 1)
    .ToList()
    .ForEach(s => Console.WriteLine(s));

Impressões:

2
3
Sergey Teplyakov
fonte
6
Em C # não use _como parâmetro de entrada no lambda. _às vezes é usado quando os parâmetros são ignorados, use x. stackoverflow.com/questions/424775/…
Carlos Muñoz
28

De acordo com este site, é uma referência this, principalmente em loops.

$ _ (sublinhado em dólar) token 'THIS'. Geralmente se refere ao item dentro de um loop foreach. Tarefa: Imprima todos os itens em uma coleção. Solução. ... foreach {Write-Host $ _}

Ikke
fonte
3
thisé um termo bastante confuso para a $_variável. No POO, geralmente se refere à classe, não a uma variável.
oɔɯǝɹ
1
@remco, especialmente quando o PS v5 adiciona uma variável $ this para uso em classes.
Xalorous
5

$ _ é um alias para a variável automática $ PSItem (introduzida no PowerShell V3.0; informações de uso encontradas aqui ) que representam o item atual do canal.

A documentação on-line do PowerShell (v6.0) para variáveis ​​automáticas é aqui .

Xalorous
fonte
1

$ _ é uma variável que itera sobre cada objeto / elemento passado da anterior | (tubo).

Conta
fonte
1

$_é uma variável criada pelo sistema geralmente dentro de expressões de bloco que são referenciadas por cmdlets usados ​​com pipe, como Where-ObjecteForEach-Object .

Mas pode ser usado também em outros tipos de expressões, por exemplo, Select-Objectcombinado com propriedades de expressão. Get-ChildItem | Select-Object @{Name="Name";Expression={$_.Name}}. Nesse caso, $_representa o item que está sendo canalizado, mas podem existir várias expressões.

Também pode ser referenciado pela validação de parâmetro personalizado, em que um bloco de script é usado para validar um valor. Nesse caso, o $_representa o valor do parâmetro recebido da chamada.

A analogia mais próxima de c # e java é a expressão lamda. Se você dividir o PowerShell com o básico, tudo será um bloco de script, incluindo um arquivo de script a, funções e cmdlets. Você pode definir seus próprios parâmetros, mas, em algumas ocasiões, um é criado pelo sistema para você, que representa o item de entrada a ser processado / avaliado . Nessas situações, a variável automática é $_.

Alex Sarafian
fonte