Como posso verificar se uma sequência é nula ou vazia no PowerShell?


413

Existe uma IsNullOrEmptyfunção interna incorporada para verificar se uma sequência é nula ou vazia no PowerShell?

Não consegui encontrá-lo até agora e, se houver uma maneira interna, não quero escrever uma função para isso.



8
Bem, você está usando .NET, então você não pode ligar String.IsNullOrEmpty?
perfil completo de Jon Skeet

Respostas:


471

Você pode usar o IsNullOrEmptymétodo estático:

[string]::IsNullOrEmpty(...)

3
Eu gosto mais desse modo, pois é óbvio o que ele faz, independentemente do seu conhecimento sobre Powerhsell - o que faria sentido para programadores que não são do PowerShell.
pencilCake

18
Eu acho que você pode fazer! $ Var #
Shay Levy

4
Uma coisa a ter em atenção no PowerShell é que as cadeias nulas passadas para um comando ou função não permanecem nulas. Eles são convertidos em cadeias vazias. Consulte o bug do Microsoft Connect em connect.microsoft.com/PowerShell/feedback/details/861093/… .
JamieSee

25
Considere [String] :: IsNullOrWhiteSpace (...) também para validar espaços vazios.
Sai

3
@ ShayLevy Cuidado com o !. Isso funciona apenas nas versões mais recentes do PowerShell. !é um alias para-not
Kolob Canyon

598

Vocês estão fazendo isso muito difícil. O PowerShell lida com isso de maneira bastante elegante, por exemplo:

> $str1 = $null
> if ($str1) { 'not empty' } else { 'empty' }
empty

> $str2 = ''
> if ($str2) { 'not empty' } else { 'empty' }
empty

> $str3 = ' '
> if ($str3) { 'not empty' } else { 'empty' }
not empty

> $str4 = 'asdf'
> if ($str4) { 'not empty' } else { 'empty' }
not empty

> if ($str1 -and $str2) { 'neither empty' } else { 'one or both empty' }
one or both empty

> if ($str3 -and $str4) { 'neither empty' } else { 'one or both empty' }
neither empty

30
@pencilCake Sim, o que estou dizendo e o exemplo acima mostram isso em ação. O que o teste não verificará é IsNullOrWhitespace ().
Keith Hill

3
Concordo com esta solução melhor do ponto de vista de script. Como sempre, Keith Hill tem a solução correta! Obrigado.
Vippy

2
Você diz elegante, mas por algum motivo, isso parece JS.
Dan Atkinson

2
@VertigoRay Veja meu primeiro comentário acima, onde eu recomendo usar IsNullOrWhitespace()para esse cenário. Mas, após 11 anos de script com o PowerShell, acho que preciso muito raramente desse teste de string . :-)
Keith Hill

3
"KeithHill. Desculpe, ainda não é seguro, pois sua intenção não é clara. Quando você usa [string] :: IsNullOrEmpty, você é absolutamente claro. IMO, o Powershell é uma criação mais estranha - na maioria das vezes é exageradamente rico, mas ainda assim . fundamentos faltando -isNullOrEmpty predicado é um deles ...
Dmitry

40

Além de, a [string]::IsNullOrEmptyfim de verificar se há nulo ou vazio, você pode converter uma string em um booleano explicitamente ou em expressões booleanas:

$string = $null
[bool]$string
if (!$string) { "string is null or empty" }

$string = ''
[bool]$string
if (!$string) { "string is null or empty" }

$string = 'something'
[bool]$string
if ($string) { "string is not null or empty" }

Resultado:

False
string is null or empty

False
string is null or empty

True
string is not null or empty

4
Bom ponto. Ifcláusula converte internamente tudo dentro dos parênteses em booleano único, o que significa if($string){Things to do for non-empty-nor-null}ou if(!$string){Things to do for empty-or-null}sem conversão explícita [bool]seria suficiente.
Ch.Idea

20

Se for um parâmetro em uma função, você pode validá-lo ValidateNotNullOrEmptycomo pode ver neste exemplo:

Function Test-Something
{
    Param(
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$UserName
    )

    #stuff todo
}

10

Pessoalmente, não aceito um espaço em branco ($ STR3) como 'não vazio'.

Quando uma variável que contém apenas espaços em branco é passada para um parâmetro, muitas vezes ocorre um erro de que o valor dos parâmetros não pode ser '$ null', em vez de dizer que pode não ser um espaço em branco, alguns comandos de remoção podem remover uma pasta raiz em vez de um subpasta se o nome da subpasta for um "espaço em branco", todo o motivo para não aceitar uma sequência que contenha espaços em branco em muitos casos.

Acho que essa é a melhor maneira de fazer isso:

$STR1 = $null
IF ([string]::IsNullOrWhitespace($STR1)){'empty'} else {'not empty'}

Esvaziar

$STR2 = ""
IF ([string]::IsNullOrWhitespace($STR2)){'empty'} else {'not empty'}

Esvaziar

$STR3 = " "
IF ([string]::IsNullOrWhitespace($STR3)){'empty !! :-)'} else {'not Empty :-('}

Esvaziar!! :-)

$STR4 = "Nico"
IF ([string]::IsNullOrWhitespace($STR4)){'empty'} else {'not empty'}

Não está vazio


5

Eu tenho um script do PowerShell que preciso executar em um computador tão desatualizado que não tenha [String] :: IsNullOrWhiteSpace (), então escrevi o meu.

function IsNullOrWhitespace($str)
{
    if ($str)
    {
        return ($str -replace " ","" -replace "`t","").Length -eq 0
    }
    else
    {
        return $TRUE
    }
}

5
# cases
$x = null
$x = ''
$x = ' '

# test
if ($x -and $x.trim()) {'not empty'} else {'empty'}
or
if ([string]::IsNullOrWhiteSpace($x)) {'empty'} else {'not empty'}

3

A substituição do PowerShell 2.0 para [string]::IsNullOrWhiteSpace()éstring -notmatch "\S"

(" \ S " = qualquer caractere que não seja um espaço em branco)

> $null  -notmatch "\S"
True
> "   "  -notmatch "\S"
True
> " x "  -notmatch "\S"
False

O desempenho é muito próximo:

> Measure-Command {1..1000000 |% {[string]::IsNullOrWhiteSpace("   ")}}
TotalMilliseconds : 3641.2089

> Measure-Command {1..1000000 |% {"   " -notmatch "\S"}}
TotalMilliseconds : 4040.8453

1

Outra maneira de fazer isso de uma maneira pura do PowerShell seria fazer algo assim:

("" -eq ("{0}" -f $val).Trim())

Isso avalia com êxito se há nulo, sequência vazia e espaço em branco. Estou formatando o valor passado em uma string vazia para manipular nulo (caso contrário, um nulo causará um erro quando o Trim for chamado). Em seguida, basta avaliar a igualdade com uma string vazia. Acho que ainda prefiro o IsNullOrWhiteSpace, mas se você estiver procurando outra maneira de fazer isso, isso funcionará.

$val = null    
("" -eq ("{0}" -f $val).Trim())
>True
$val = "      "
("" -eq ("{0}" -f $val).Trim())
>True
$val = ""
("" -eq ("{0}" -f $val).Trim())
>True
$val = "not null or empty or whitespace"
("" -eq ("{0}" -f $val).Trim())
>False

Em um ataque de tédio, eu brinquei com isso um pouco e o tornei mais curto (embora mais enigmático):

!!(("$val").Trim())

ou

!(("$val").Trim())

dependendo do que você está tentando fazer.


1

Observe que os testes "if ($str)"e "IsNullOrEmpty"não funcionam comparativamente em todas as instâncias: uma atribuição de $str=0produz false para ambos e, dependendo da semântica pretendida do programa, isso pode causar uma surpresa.


$ str = 0 não é uma boa prática de codificação. $ str = '0' não deixará dúvidas sobre qual é o resultado esperado de IsNullOrEmpty.
dmitry

-1

Verifique o comprimento. Se o objeto existir, ele terá um comprimento.

Objetos nulos não têm comprimento, não existem e não podem ser verificados.

O objeto String tem um comprimento.

A pergunta era: IsNull ou IsEmpty, NOT IsNull ou IsEmpty ou IsWhiteSpace

#Null
$str1 = $null
$str1.length
($str1 | get-member).TypeName[0]
# Returns big red error

#Empty
$str2 = ""
$str2.length
($str2 | get-member).TypeName[0]
# Returns 0

## Whitespace
$str3 = " "
$str3.length
($str3 | get-member).TypeName[0]
## Returns 1 

2
RE Null objects have no length- você já tentou executar $null.length? :-) Para um teste rápido de bool, passar para Get-Member e depois ter que lidar com o erro resultante para o caso $ null parece um pouco pesado para mim.
Keith Hill
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.