¿Cómo puedo verificar si una cadena es nula o está vacía en PowerShell?

413

¿Hay un incorporado IsNullOrEmpty similar para verificar si una cadena es nula o vacía, en PowerShell?

No pude encontrarlo hasta ahora y si hay una forma integrada, no quiero escribir una función para esto.

lápiz de pastel
fuente
2
Espero que
gofor.net
8
Bueno, estás usando .NET, ¿no puedes llamar String.IsNullOrEmpty?
Jon Skeet

Respuestas:

471

Puedes usar el IsNullOrEmptymétodo estático:

[string]::IsNullOrEmpty(...)
Shay Levy
fuente
3
Me gusta más de esta manera, ya que es obvio lo que hace independientemente de su conocimiento de Powerhsell, lo que tendría sentido para los programadores que no son Powershell.
pencilCake
18
¡Supongo que puedes hacerlo! $ Var
Shay Levy
44
Una cosa a tener en cuenta con PowerShell es que las cadenas nulas pasadas a un comando o función no permanecen nulas. Se convierten en cadenas vacías. Consulte el error de Microsoft Connect en connect.microsoft.com/PowerShell/feedback/details/861093/… .
JamieVer
25
Considere [String] :: IsNullOrWhiteSpace (...) para validar también los espacios vacíos.
Sai
3
@ShayLevy Cuidado con el !. Eso solo funciona en las versiones más nuevas de PowerShell. !es un alias para-not
Kolob Cañón
598

Ustedes están haciendo esto demasiado difícil. PowerShell maneja esto con bastante elegancia, por ejemplo:

> $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
fuente
30
@pencilCake Sí, eso es lo que digo y el ejemplo anterior lo muestra en acción. Lo que la prueba no comprobará es IsNullOrWhitespace ().
Keith Hill
3
Estoy de acuerdo con esta solución mejor desde un punto de vista de secuencias de comandos. ¡Como siempre, Keith Hill tiene la solución correcta! Gracias.
Vippy
2
Dices elegante, pero por alguna razón, esto se siente como JS.
Dan Atkinson
2
@VertigoRay Vea mi primer comentario arriba donde recomiendo usar IsNullOrWhitespace()para ese escenario. Pero después de 11 años de secuencias de comandos con PowerShell, encuentro que necesito esa prueba de cadena muy raramente . :-)
Keith Hill
3
"KeithHill. Perdón, eso sigue siendo inseguro, ya que su intención no está clara. Cuando usa [string] :: IsNullOrEmpty, está absolutamente claro. En mi opinión, Powershell es una creación extraña, la mayoría de las veces es excesivamente rica, pero aún así faltan elementos esenciales. -esNullOrEmpty predicado es uno de ellos ...
dmitry
40

Además de [string]::IsNullOrEmpty , para verificar si es nulo o está vacío, puede convertir una cadena a un booleano explícitamente o en expresiones 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" }

Salida:

False
string is null or empty

False
string is null or empty

True
string is not null or empty
Roman Kuzmin
fuente
44
Buen punto IfLa cláusula convierte internamente todo dentro del paréntesis en booleano único, lo que significa que if($string){Things to do for non-empty-nor-null}o if(!$string){Things to do for empty-or-null}sin conversión explícita [bool]sería suficiente.
Ch.Idea
20

Si es un parámetro en una función, puede validarlo ValidateNotNullOrEmptycomo se puede ver en este ejemplo:

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

    #stuff todo
}
Rubanov
fuente
10

Personalmente, no acepto un espacio en blanco ($ STR3) como "no vacío".

Cuando una variable que solo contiene espacios en blanco se pasa a un parámetro, a menudo se producirá un error que el valor de los parámetros puede no ser '$ nulo', en lugar de decir que no puede ser un espacio en blanco, algunos comandos de eliminación pueden eliminar una carpeta raíz en lugar de un subcarpeta si el nombre de la subcarpeta es un "espacio en blanco", todo el motivo para no aceptar una cadena que contenga espacios en blanco en muchos casos.

Creo que esta es la mejor manera de lograrlo:

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

Vacío

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

Vacío

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

¡¡Vacío!! :-)

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

No vacío

Nico van der Stok
fuente
5

Tengo un script de PowerShell que tengo que ejecutar en una computadora tan desactualizada que no tiene [String] :: IsNullOrWhiteSpace (), así que escribí el mío.

function IsNullOrWhitespace($str)
{
    if ($str)
    {
        return ($str -replace " ","" -replace "`t","").Length -eq 0
    }
    else
    {
        return $TRUE
    }
}
mhenry1384
fuente
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
fuente
3

Reemplazo de PowerShell 2.0 para [string]::IsNullOrWhiteSpace() esstring -notmatch "\S"

(" \ S " = cualquier carácter que no sea un espacio en blanco)

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

El rendimiento está muy cerca:

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

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

Otra forma de lograr esto de una manera pura de PowerShell sería hacer algo como esto:

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

Esto evalúa con éxito la cadena nula, vacía y el espacio en blanco. Estoy formateando el valor pasado en una cadena vacía para manejar nulo (de lo contrario, un nulo causará un error cuando se llame a Trim). Luego solo evalúa la igualdad con una cadena vacía. Creo que todavía prefiero el IsNullOrWhiteSpace, pero si está buscando otra forma de hacerlo, esto 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

En un ataque de aburrimiento, jugué con esto y lo hice más corto (aunque más críptico):

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

o

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

dependiendo de lo que intentes hacer.

Ryan
fuente
1

Tenga en cuenta que las pruebas "if ($str)"y "IsNullOrEmpty"no funcionan de manera comparable en todos los casos: una asignación de $str=0produce falso para ambos, y dependiendo de la semántica del programa previsto, esto podría dar una sorpresa.

Steve Friedl
fuente
$ str = 0 no es una buena práctica de codificación. $ str = '0' no dejará ninguna duda sobre cuál es el resultado esperado de IsNullOrEmpty.
dmitry
-1

Verifica la longitud. Si el objeto existe, tendrá una longitud.

Los objetos nulos no tienen longitud, no existen y no se pueden verificar.

El objeto de cadena tiene una longitud.

La pregunta era: IsNull o IsEmpty, NOT IsNull o IsEmpty o 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 
Luke B_
fuente
2
RE Null objects have no length: ¿has intentado ejecutar $null.length? :-) Para una prueba rápida de bool, conectarme a Get-Member y luego tener que manejar el error resultante para el caso $ null me parece un poco pesado.
Keith Hill el