Jak mogę sprawdzić, czy ciąg jest pusty lub pusty w PowerShell?

413

Czy IsNullOrEmptyw programie PowerShell jest wbudowana funkcja podobna do sprawdzania, czy łańcuch jest pusty lub pusty?

Do tej pory nie mogłem go znaleźć, a jeśli istnieje wbudowany sposób, nie chcę do tego pisać funkcji.

ołówek Ciasto
źródło
2
hop to pomaga rkeithhill.wordpress.com/2007/01/06/…
gofor.net
8
Używasz .NET, więc nie możesz zadzwonić String.IsNullOrEmpty?
Jon Skeet,

Odpowiedzi:

471

Możesz użyć IsNullOrEmptymetody statycznej:

[string]::IsNullOrEmpty(...)
Shay Levy
źródło
3
Podoba mi się to w ten sposób, ponieważ jest oczywiste, co robi bez względu na twoją wiedzę Powerhsell - co miałoby sens dla programistów spoza Powershell.
pencilCake
18
Myślę, że możesz to zrobić! $ Var
Shay Levy
4
Jedną z rzeczy, o których należy pamiętać w programie PowerShell, jest to, że ciągi zerowe przekazywane do komendy lub funkcji nie pozostają puste. Przekształcają się w puste ciągi. Zobacz błąd Microsoft Connect w connect.microsoft.com/PowerShell/feedback/details/861093/... .
JamieSee
25
Rozważ [Ciąg] :: IsNullOrWhiteSpace (...) również do sprawdzania poprawności pustych miejsc.
Sai
3
@ShayLevy Ostrożnie z !. Działa to tylko w nowszych wersjach programu PowerShell. !jest pseudonimem-not
Kolob Canyon
598

Robicie to zbyt ciężko. PowerShell obsługuje to dość elegancko, np .:

> $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
Keith Hill
źródło
30
@pencilCake Tak, to, co mówię i powyższy przykład pokazuje to w działaniu. To, czego test nie sprawdzi, to IsNullOrWhitespace ().
Keith Hill,
3
Zgadzam się z tym rozwiązaniem lepiej z punktu widzenia skryptów. Jak zawsze Keith Hill ma właściwe rozwiązanie! Dzięki.
Vippy
2
Mówisz elegancko, ale z jakiegoś powodu wydaje się, że to JS.
Dan Atkinson
2
@VertigoRay Zobacz mój pierwszy komentarz powyżej, w którym zalecam użycie IsNullOrWhitespace()tego scenariusza. Ale po 11 latach pisania skryptów w PowerShell bardzo rzadko potrzebuję tego testu ciągów . :-)
Keith Hill
3
„KeithHill. Przepraszam, to wciąż niebezpieczne, ponieważ twoja intencja nie jest jasna. Kiedy używasz [string] :: IsNullOrEmpty, masz absolutną jasność. IMO, Powershell jest dziwnym dziełem - przez większość czasu jest zbyt bogaty, ale wciąż brakuje niezbędnych rzeczy. -isNullOrEmpty predicate jest jednym z nich ...
dmitry
40

Oprócz tego [string]::IsNullOrEmpty, aby sprawdzić, czy jest pusta lub pusta, możesz rzutować ciąg znaków na wartość logiczną jawnie lub w wyrażeniach logicznych:

$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" }

Wynik:

False
string is null or empty

False
string is null or empty

True
string is not null or empty
Roman Kuźmin
źródło
4
Niezły punkt. Ifklauzula wewnętrznie konwertuje wszystko w nawiasie na pojedynczy logiczny, co oznacza, że wystarczy jawna konwersja if($string){Things to do for non-empty-nor-null}lub if(!$string){Things to do for empty-or-null}bez [bool]niej.
Ch.Idea
20

Jeśli jest to parametr w funkcji, możesz go zweryfikować, ValidateNotNullOrEmptyjak widać w tym przykładzie:

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

    #stuff todo
}
Rubanow
źródło
10

Osobiście nie akceptuję spacji ($ STR3) jako „niepusty”.

Gdy zmienna zawierająca tylko białe znaki jest przekazywana do parametru, często będzie błąd, że wartość parametru nie może być równa „$ null”, zamiast powiedzieć, że nie może to być biała spacja, niektóre polecenia usuwania mogą usunąć folder główny zamiast podfolder, jeśli nazwa podfolderu to „biała spacja”, powodem tego jest to, że w wielu przypadkach nie można zaakceptować ciągu zawierającego białe znaki.

Uważam, że jest to najlepszy sposób na osiągnięcie tego:

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

Pusty

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

Pusty

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

Pusty!! :-)

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

Nie pusty

Nico van der Stok
źródło
5

Mam skrypt PowerShell, który muszę uruchamiać na komputerze tak nieaktualnym, że nie ma on [String] :: IsNullOrWhiteSpace (), więc napisałem własny.

function IsNullOrWhitespace($str)
{
    if ($str)
    {
        return ($str -replace " ","" -replace "`t","").Length -eq 0
    }
    else
    {
        return $TRUE
    }
}
mhenry1384
źródło
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'}
Skatterbrainz
źródło
3

Zamiennik PowerShell 2.0 dla [string]::IsNullOrWhiteSpace()isstring -notmatch "\S"

(„ \ S ” = dowolny znak inny niż biały)

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

Wydajność jest bardzo bliska:

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

> Measure-Command {1..1000000 |% {"   " -notmatch "\S"}}
TotalMilliseconds : 4040.8453
Nikolay Polyagoshko
źródło
1

Innym sposobem osiągnięcia tego w czysty sposób PowerShell byłoby zrobienie czegoś takiego:

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

Sprawdza to z powodzeniem dla pustego, pustego łańcucha i białych znaków. Formatuję przekazaną wartość do pustego ciągu, aby obsługiwał wartość NULL (w przeciwnym razie wartość NULL spowoduje błąd podczas wywoływania Trim). Następnie po prostu oceń równość pustym ciągiem. Myślę, że nadal wolę IsNullOrWhiteSpace, ale jeśli szukasz innego sposobu, to zadziała.

$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

W przypływie nudy trochę się tym bawiłem i skróciłem (choć bardziej tajemniczo):

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

lub

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

w zależności od tego, co próbujesz zrobić.

Ryan
źródło
1

Zauważ, że "if ($str)" i "IsNullOrEmpty"testy nie działają porównywalnie we wszystkich przypadkach: cesja $str=0produkuje fałszywe dla obu, i w zależności od zamierzonych semantyki programu, może to wydajność niespodziankę.

Steve Friedl
źródło
$ str = 0 nie jest dobrą praktyką kodowania. $ str = „0” nie pozostawia wątpliwości co do oczekiwanego wyniku IsNullOrEmpty.
dmitry
-1

Sprawdź długość. Jeśli obiekt istnieje, będzie miał długość.

Obiekty zerowe nie mają długości, nie istnieją i nie można ich sprawdzić.

Obiekt string ma długość.

Pytanie brzmiało: IsNull lub IsEmpty, NOT IsNull lub IsEmpty lub 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 
Łukasz B_
źródło
2
RE Null objects have no length- próbowałeś wykonać $null.length? :-) Dla szybkiego testu bool, pipowanie do Get-Member, a następnie konieczność obsługi wynikowego błędu w przypadku $ null wydaje mi się nieco ciężki.
Keith Hill