Por que o Powershell converte silenciosamente um array de strings com um item em uma string?

27

Considere o seguinte script Powershell, que pesquisa por pastas em C: \ com um 'og' em seu nome:

PS C:\> (ls | %{$_.Name} | ?{$_.Contains("og")})
PerfLogs
Program Files
setup.log

Agora refino a pesquisa para obter apenas um item:

PS C:\> (ls | %{$_.Name} | ?{$_.Contains("Prog")})
Program Files

O mais estranho é que a primeira operação produz um array , enquanto a segunda operação (que é IMHO semanticamente a mesma operação, então deve render o mesmo tipo de resultado) produz um string . Isso pode ser visto no seguinte resultado:

PS C:\> (ls | %{$_.Name} | ?{$_.Contains("og")}).Length
3
PS C:\> (ls | %{$_.Name} | ?{$_.Contains("Prog")}).Length
13

Isso pode ser muito irritante, já que aparentemente há menos pastas que combinam 'og' do que aquelas que combinam com 'Prog'.

Evidentemente, o PowerShell implicitamente "desencaixa" uma matriz de item único para um único objeto, e nunca obtemos uma matriz de tamanho 1. Parece que toda vez que quero contar os resultados que passam pelo pipeline, preciso verificar se estou lidando com uma matriz ou não.

Como posso evitar que isso aconteça? Como você lida com isso?

    
por cheeesus 20.04.2012 / 10:47

3 respostas

44

Evidently, PowerShell implicitly 'unboxes' a single-item array to a single object,

E zero item resulta em $null .

How can I prevent this from happening?

Você não pode.

How do you deal with this?

Use o construtor de matriz ( @(...) ) para forçar uma coleta (possivelmente com zero ou um elemento) return:

$res = @(ls | %{$_.Name} | ?{$_.Contains("Prog")})
    
por 20.04.2012 / 12:17
2

Isso foi resolvido no PowerShell v3:

link

Em uma nota lateral, você pode descobrir se um nome contém algo usando um caractere curinga:

PS> ls *og*
    
por 20.04.2012 / 20:07
0

Observe a diferença entre esses dois resultados:

PS C:\> ConvertTo-Json -InputObject @(1)
[
    1
]
PS C:\> @(1)|ConvertTo-Json
1
PS C:\>

O ponto é que o 'unboxing' está sendo feito pela operação de pipe. O ConvertTo-Json ainda vê o objeto como uma matriz se usarmos InputObject em vez de piping.

    
por 03.08.2018 / 05:18