Maestro de PowerShell: Concatenar, Dividir y Más

Cadenas en PowerShell son probablemente el tipo de datos más utilizado en PowerShell. Desde mostrar mensajes, solicitar entrada o enviar datos a archivos, es casi imposible escribir scripts sin que las cadenas estén involucradas.

En este artículo, aprenderás que las cadenas no solo son para leer y mostrar. También se pueden manipular para adaptarse al propósito de la tarea para la cual estás escribiendo el script. Como reemplazar caracteres o palabras enteras, concatenar cadenas para formar una nueva cadena, o incluso dividir una cadena en múltiples cadenas.

Comprendiendo las Cadenas

Según la definición de .NET de cadena – “Una cadena es una colección secuencial de caracteres que se utiliza para representar texto”. En resumen, siempre que haya una secuencia de caracteres formando un texto, hay una cadena.

Definiendo Cadenas del Sistema en PowerShell

Las cadenas se definen al encerrar una serie de caracteres entre comillas simples o dobles. A continuación se presentan ejemplos de una cadena.

PS> 'Hello PowerShell - Today is $(Get-Date)'PS> "Hello PowerShell - Today is $(Get-Date)"

Las cadenas son, de hecho, System.Strings en .NET.

Como puedes ver en el ejemplo anterior, la primera cadena está encerrada con comillas simples y la segunda cadena está encerrada en comillas dobles. Si te preguntas, la única diferencia entre las dos es que las cadenas entre comillas dobles admiten expansión de cadena, mientras que las comillas simples solo representarán cadenas literales.

Para confirmar el concepto de comillas simples frente a comillas dobles, cuando pegas ambas cadenas del ejemplo anterior en PowerShell.

La captura de pantalla a continuación muestra que una cadena entre comillas simples devuelve la cadena literal exacta que se definió. Mientras que la cadena entre comillas dobles devuelve la cadena con el resultado de la expresión del cmdlet Get-Date.

Single Quote vs. Double-Quote String Output

El resultado mostrado anteriormente demuestra la distinción de cuándo es apropiado usar comillas simples o dobles al definir cadenas.

El Objeto de Cadena

Como se mencionó en la sección anterior, la colección de caracteres que forma un texto es una cadena. El valor resultante de la cadena es el objeto String. El objeto String es un objeto .NET que pertenece al tipo [System.String].

Y dado que System.String es un objeto, tiene propiedades a las que puedes acceder utilizando el cmdlet Get-Member. A continuación, estamos insertando una variable dentro de una cadena con comillas dobles.

PS> "Hello PowerShell - Today is $(Get-Date)" | Get-Member=

La captura de pantalla a continuación muestra el TypeName y la lista parcial de propiedades del objeto String.

String Object properties

Concatenación de Cadenas en PowerShell

La concatenación de cadenas se describe como la unión de dos o más cadenas, creando esencialmente un objeto de cadena a partir de varios objetos de cadena separados. Hay varios métodos en PowerShell para concatenar cadenas. Cada método es diferente y cuál usar depende de cómo planeas implementar la concatenación de cadenas.

A typical example of using string concatenation in the real world is Active Directory user creation. Perhaps you’re creating a user creation script that takes the first name, last name, and department values from a list.

Usando la concatenación de cadenas, puedes formular la convención de nomenclatura estándar para el nombre, nombre para mostrar, nombre de usuario y dirección de correo electrónico. Para este ejemplo, trabajarás con las cadenas que se muestran a continuación. Copia este código y pégalo en tu sesión de PowerShell.

$domain = 'contoso.com'
$firstname = 'Jack'
$lastname = 'Ripper'
$department = 'Health'

Usando los valores de variables de ejemplo anteriores, el objetivo es derivar los siguientes valores listados a continuación concatenando cadenas.

  • Nombre = nombre apellido
  • Nombre para mostrar = nombre apellido (departamento)
  • SamAccountName = nombre.apellido
  • Dirección de correo electrónico = [email protected]

En las siguientes secciones, los valores mencionados anteriormente se crearán utilizando los diferentes métodos de concatenación de cadenas disponibles en PowerShell.

¡Comencemos!

Usando el Operador de Concatenación de Cadenas de PowerShell

Los lenguajes de programación tienen su propio operador de concatenación de cadenas utilizado para concatenar cadenas. Por ejemplo, en Visual Basic, el método de concatenación es el signo ampersand (&). PowerShell también tiene su propio método de concatenación, que es el signo más (+).

Usando el operador de concatenación de cadenas, puedes concatenar cadenas usando el código siguiente.

## Nombre
$firstname + ' ' + $lastname
## Nombre para mostrar
$firstname + ' ' + $lastname + ' (' + $department + ')'
## SamAccountName
$firstname + '.' + $lastname
## Dirección de correo electrónico
$firstname + '.' + $lastname + '@' + $domain

Utilizando la Expansión de Cadenas en PowerShell

El uso de la expansión de cadenas podría ser el método que resulta en el código más breve al concatenar cadenas. Como se puede ver en el código a continuación, todo lo que se necesita es organizar las cadenas como deberían aparecer y encerrarlas entre comillas dobles.

# Utilizando la Expansión de Cadenas
## Nombre
"$firstname $lastname"
## Nombre para Mostrar
"$firstname $lastname ($department)"
## SamAccountName
"$firstname.$lastname"
## Dirección de Correo Electrónico
"$firstname.$lastname@$domain"

Luego, PowerShell interpreta y maneja la expansión de cadenas dentro de las comillas dobles para producir la cadena concatenada como resultado. Puede consultar la salida de ejemplo a continuación.

Using String Expansion

Utilizando el Operador de Formato en PowerShell

El operador de formato (-f) se utiliza principalmente para el formato compuesto. Lo importante de recordar con este método es que hay tres partes al usar -f.

Consulte la tercera línea del código a continuación. La "{0} {1}" representa el formato y los marcadores de posición. Los números entre las llaves indican el índice de la cadena en la colección que se mostrará en su lugar. Las comillas pueden ser simples o dobles.

La colección de cadenas de entrada en este ejemplo está representada por $nombre, $apellido. Esto significa que el índice de la variable $nombre es 0, mientras que el de $apellido es 1.

Finalmente, -f es el lugar entre el marcador de posición y la colección de cadenas representadas por (-f).

## Nombre
"{0} {1}" -f $firstname,$lastname
## Nombre a mostrar
"{0} {1} ({2})" -f $firstname,$lastname,$department
## Nombre de la cuenta Sam
"{0}.{1}" -f $firstname,$lastname
## Dirección de correo electrónico
"{0}.{1}@{2}" -f $firstname,$lastname,$domain

El código anterior resultará en los resultados mostrados a continuación.

Using the Format Operator

Usando el operador -Join de PowerShell

El operador -Join se puede usar para unir cadenas en una sola cadena de dos maneras.

La primera forma de usar -Join es siguiéndolo con el array de cadenas que desea concatenar. El operador -Join no proporciona una opción para agregar un delimitador. Todas las cadenas en el array se unirán sin nada en medio.

-Join <String[]>

La segunda forma de usar el operador -Join es especificar el delimitador a usar. El array de cadenas se unirá, pero el carácter delimitador especificado se insertará entre cada cadena.

<String[]> -Join <Delimiter>

Volviendo al objetivo de concatenar cadenas, el siguiente código demuestra cómo usar el operador -Join para unir cadenas.

## Nombre
$firstname, $lastname -join ' '
## Nombre a mostrar
$firstname,$lastname,"($department)" -join ' '
## Nombre de la cuenta Sam
-join ($firstname,'.',$lastname)
## Dirección de correo electrónico
-join ($firstname,'.',$lastname,'@',$domain)

Cuando ejecutas el código de ejemplo anterior en PowerShell, esperarías ver una salida similar a la que se muestra a continuación.

Using the PowerShell Join Operator

El Método String.Format() de .NET

El método String.Format de .NET es el equivalente en .NET del Operador de Formato de PowerShell. Funciona de la misma manera que el operador de formato donde se deben especificar el formato y los marcadores de posición.

## Nombre
[string]::Format("{0} {1}",$firstname,$lastname)
## Nombre para Mostrar
[string]::Format("{0} {1} ({2})",$firstname,$lastname,$department)
## Nombre de Cuenta Sam
[string]::Format("{0}.{1}",$firstname,$lastname)
## Dirección de Correo Electrónico
[string]::Format("{0}.{1}@{2}",$firstname,$lastname,$domain)

La captura de pantalla a continuación muestra el Método String.Format en acción.

The .NET String.Format Method

El Método String.Concat() de .NET

Otro método para concatenar cadenas es usar el Método String.Concat de .NET. El Método String.Concat de .NET es el equivalente en .NET del Operador de Concatenación de Cadenas de PowerShell (+). Pero, en lugar de usar el signo + para unir cadenas, puedes agregar todas las cadenas dentro del método de esta manera: [string]::Concat(cadena1,cadena2...).

## Nombre
[string]::Concat($firstname,' ',$lastname)
## Nombre de visualización
[string]::Concat($firstname,' ',$lastname,' (',$department,')')
## Nombre de cuenta Sam
[string]::Concat($firstname,'.',$lastname)
## Dirección de correo electrónico
[string]::Concat($firstname,'.',$lastname,'@',$domain)

La captura de pantalla a continuación muestra el resultado de invocar el método .NET String.Concat. Puede ver que PowerShell ha fusionado string1, string2.

Using the .NET String.Concat Method

El Método String.Join() de .NET

El método String.Join de .NET es el equivalente del método en .NET al Operador de Unión de PowerShell (-join). El formato para este método es [string]::Join(<delimiter>,<string1>,<string2>,...).

El primer elemento dentro del método -Join siempre es el delimitador. Luego, los valores de los elementos siguientes son las cadenas que desea concatenar. Vea el código de ejemplo a continuación. Recuerde, el primer elemento siempre es el delimitador. Si no desea agregar un delimitador, puede especificarlo de esta manera —> ''.

## Nombre
[string]::Join(' ',$firstname,$lastname)
## Nombre de visualización
[string]::Join(' ',$firstname,$lastname,"($department)")
## Nombre de cuenta Sam
[string]::Join('',$firstname,'.',$lastname)
## Dirección de correo electrónico
[string]::Join('',$firstname,'.',$lastname,'@',$domain)
The .NET String.Join Method

División de Cadenas en PowerShell

Ha visto varios métodos diferentes para concatenar cadenas en la sección anterior. En esta sección, aprenderá sobre las diferentes formas de usar PowerShell para dividir cadenas. Dividir cadenas es la acción inversa a la concatenación.

Puedes dividir cadenas en PowerShell de dos maneras diferentes: mediante la función/método split() o mediante el operador split.

División de Cadenas con el Método Split()

Si buscas una forma sencilla de dividir una cadena para crear un array, no busques más allá del método split(). Este método está presente en cada objeto de cadena y es capaz de dividir una cadena en un array según un carácter no-regex.

Por ejemplo, si tienes una cadena como verde|huevos|y|jamón y deseas crear un array como @('verde','huevos','y','jamón'), puedes dividir esta cadena en el símbolo de la barra vertical (|), como se muestra en el siguiente fragmento de código.

$string = 'green|eggs|and|ham'
$string.split('|')

Luego verás que PowerShell ha dividido la cadena en el array deseado con el símbolo de la barra vertical.

El método split() es una forma sencilla de dividir cadenas pero tiene limitaciones. No permite dividir cadenas mediante expresiones regulares. Si necesitas capacidades más avanzadas para dividir una cadena, deberás aprender sobre el operador split.

El Operador -split

El principal operador que se puede utilizar para dividir cadenas en PowerShell es el operador -Split. Usando este operador, las cadenas se dividen por espacios en blanco de forma predeterminada, o con caracteres delimitadores específicos.

A continuación, se muestra la sintaxis del operador -Split para tu referencia. Recuerda notar la diferencia entre la división unaria y binaria.

# Separación Unaria
-Split <String>
-Split (<String[]>)

# Separación Binaria
<String> -Split <Delimiter>[,<Max-substrings>[,"<Options>"]]
<String> -Split {<ScriptBlock>} [,<Max-substrings>]

En este ejemplo, la variable $string contiene el valor de una cadena de una sola línea. Luego, con el operador -Split, la cadena de una sola línea se dividirá en una matriz de cadenas de PowerShell. La cadena dividida resultante se guarda en la variable $split.

## División de Cadenas en Subcadenas
# Asignar un valor de cadena a la variable $string
$string = 'This sentence will be split between whitespaces'
# Dividir el valor de $string y almacenar el resultado en la variable $split
$split = -split $string
# Obtener el recuento de subcadenas resultantes
$split.Count
# Mostrar las subcadenas resultantes
$split

Como se puede ver en el resultado anterior, lo que era originalmente una sola cadena se dividió en 7 subcadenas. Esto demuestra cómo PowerShell divide una cadena en una matriz.

El Delimitador de Caracteres

En el ejemplo anterior, el operador -Split dividió el objeto de cadena única en varias subcadenas incluso sin especificar un delimitador; esto se debe a que el delimitador predeterminado del operador -Split es el espacio en blanco. Sin embargo, los delimitadores también pueden ser caracteres, cadenas, patrones o bloques de script.

En este ejemplo, el delimitador utilizado es el punto y coma ;.

## División de cadenas en subcadenas con delimitador
# Asigne un valor de cadena a la variable $string
$string = 'This;sentence;will;be;split;between;semicolons'
# Divida el valor de $string y almacene el resultado en la variable $split
$split = $string -split ";"
# Obtenga el recuento de las subcadenas resultantes
$split.Count
# Muestre las subcadenas resultantes
$split

Cuando pruebes el código anterior en PowerShell, obtendrás el siguiente resultado.

Splitting a String into Substrings with Character Delimiter

Te das cuenta en la salida anterior que el carácter delimitador fue omitido por completo de las subcadenas resultantes.

Si, por alguna razón, necesitas conservar el carácter delimitador, el delimitador se puede retener encerrando el carácter entre paréntesis.

$split = $string -split "(;)"
$split.Count
$split

Después de modificar el delimitador de división, como se muestra arriba, al ejecutarlo se obtendría el resultado mostrado a continuación.

Splitting a string on semicolon

El resultado anterior muestra que los caracteres delimitadores no se omiten y se cuentan en las subcadenas resultantes.

El delimitador de cadena

Las cadenas también se pueden dividir por otra cadena como delimitador. En este ejemplo, se utiliza la cadena “día” como delimitador.

$daysOfTheWeek= 'monday,tuesday,wednesday,thursday,friday,saturday,sunday'
$daysOfTheWeek -split "day"

El delimitador de bloque de script

A scriptBlock as the delimiter enables the -Split operator to perform custom or complex splitting of strings.

En los ejemplos anteriores, el carácter o cadena delimitador se utiliza para dividir las cadenas. Con el uso de un bloque de script, puedes crear una expresión que utilice efectivamente más de un delimitador.

El ejemplo a continuación utiliza la expresión {$PSItem -eq 'e' -or $PSItem -eq 'y'}, lo que significa que la cadena se dividirá si el carácter entrante es 'e' o 'a'.

$daysOfTheWeek= 'monday,tuesday,wednesday,thursday,friday,saturday,sunday'
$daysOfTheWeek -split {$PSItem -eq 'e' -or $PSItem -eq 'y'}

Y cuando ejecutas este comando, la salida será subcadenas que se dividen con los caracteres delimitadores especificados en la expresión dentro del bloque de script.

Splitting a String into Substrings with a Script Block Delimiter

Este siguiente ejemplo hace un poco más con un bloque de script. Esta vez, la expresión evalúa si:

  • El carácter entrante se pasa como un entero; y
  • Que su valor sea mayor que 1

Si el resultado de la evaluación es verdadero, entonces el operador -Split utilizará ese carácter como delimitador. Además, se agrega manejo de errores para asegurar que los errores se filtren.

$daysOfTheWeek= 'monday1tuesday2wednesday3thursday1friday4saturday8sunday'
$daysOfTheWeek -split {
    try {
        [int]$PSItem -gt 1
    }
    catch {
        #NO HACER NADA
    }
}

Después de ejecutar el código mostrado anteriormente, la expectativa es que la cadena se divida en el lugar donde el valor del carácter puede convertirse en un entero con un valor mayor que 1. Lo siguiente muestra la salida esperada.

Splitting a String into Substrings with a Script Block Delimiter

El Delimitador RegEx

Por defecto, el operador -Split utiliza RegEx coincidiendo con el delimitador especificado. Esto significa que también puedes usar RegEx como delimitadores para dividir cadenas.

En este próximo ejemplo, la cadena contiene caracteres de palabras y caracteres que no son palabras. El objetivo es dividir la cadena con cualquier carácter que no sea una palabra. En RegEx, los caracteres que no son palabras están representados por \W, mientras que los caracteres de palabras que coinciden con estos caracteres, [a-zA-Z0-9_], están representados por \w.

$daysOfTheWeek= 'monday=tuesday*wednesday^thursday#friday!saturday(sunday'
$daysOfTheWeek -split "\W"

Limitando Subcadenas

También es posible detener el operador -Split para dividir una cadena en una cantidad específica de subcadenas. La opción que se puede utilizar para limitar el resultado de la subcadena es el parámetro <Max-substrings>.

Cuando te refieres a la sintaxis de -Split, el parámetro <Max-substrings> es el parámetro que sigue directamente al parámetro <Delimited>. La sintaxis se muestra nuevamente a continuación como referencia.

<String> -Split <Delimiter>[,<Max-substrings>[,"<Options>"]]

Siguiendo la sintaxis anterior, el código de ejemplo a continuación se modifica para limitar el número de divisiones/subcadenas a 3.

$daysOfTheWeek= 'monday,tuesday,wednesday,thursday,friday,saturday,sunday'
$daysOfTheWeek -split ",",3

Y, al ejecutar el código anterior, se obtiene la siguiente salida. Como puedes ver, la cadena se dividió en solo tres subcadenas. Los delimitadores restantes se omitieron.

Limiting the Number of Substrings starting from the first 3 matched delimiters

Ahora, si deseas limitar las subcadenas, pero en orden inverso, podrías cambiar el valor del parámetro <Max-substrings> a un valor negativo. En este próximo ejemplo, <Max-substrings> se cambia a -3.

$daysOfTheWeek= 'monday,tuesday,wednesday,thursday,friday,saturday,sunday'
$daysOfTheWeek -split ",",-3

Y como resultado del código modificado anteriormente, la cadena se dividió comenzando desde los últimos tres delimitadores coincidentes.

Limiting the Number of Substrings starting from the last 3 matched delimiters

Encontrar y Reemplazar Cadenas

En esta sección, aprenderás acerca de los dos métodos que se pueden utilizar para buscar y realizar un reemplazo de cadena en PowerShell. El método Replace() y el operador -Replace.

El Método Replace()

El objeto de cadena también tiene un método incorporado que puede ayudar a realizar operaciones de búsqueda y reemplazo: el método replace(). El método replace() admite un máximo de cuatro sobrecargas.

El conjunto aceptable de sobrecargas para el método replace() se enumera a continuación.

<String>.Replace(<original>, <substitute>[, <ignoreCase>][, <culture>])

Las únicas sobrecargas requeridas son <original> y <substitute>. <ignoreCase> y <culture> son opcionales.

En el ejemplo siguiente, el código buscará todas las instancias del carácter coma (,) y las reemplazará por punto y coma (;).

$daysOfTheWeek = 'monday,tuesday,wednesday,thursday,friday,saturday,sunday'
$daysOfTheWeek.Replace(',',';')

Además de reemplazar un solo carácter, también puedes utilizar el método replace() para buscar y reemplazar cadenas. El código de ejemplo siguiente reemplaza la palabra “day” por “night”.

$daysOfTheWeek = 'monday,tuesday,wednesday,thursday,friday,saturday,sunday'
$daysOfTheWeek.Replace('day','NIGHT')
Replacing a matched string using the replace() method

El Operador -Replace

La sintaxis para el operador de reemplazo se muestra a continuación.

<string> -replace <original>, <substitute>

Utilizando la sintaxis anterior, el código de ejemplo siguiente reemplaza la palabra “day” por “Night” con el operador -replace.

$daysOfTheWeek = 'monday,tuesday,wednesday,thursday,friday,saturday,sunday'
$daysOfTheWeek -replace 'day','NIGHT'
Replacing a matched character with the -replace operator

Este próximo ejemplo utiliza una coincidencia de RegEx para reemplazar cadenas con el operador -replace. El código a continuación busca en la cadena aquí la cadena que coincide con (#.) y las reemplaza con nada.

$daysOfTheWeek = @'
1. Line 1
2. Line 2
3. Line 3
4. Line 4
5. Line 5
'@
$daysOfTheWeek -replace "\d.\s",""
Replacing a RegEx match using -replace

Extracción de Cadenas de Cadenas

El objeto de cadena tiene un método llamado SubString(). El método SubString() se utiliza para extraer cadenas dentro de cadenas en ubicaciones específicas. La sintaxis del método SubString() se muestra a continuación.

<String>.SubString(<startIndex>[,<length>])

El startIndex es el índice de posición donde el método SubString() comenzaría la búsqueda. El parámetro length indica la cantidad de caracteres a devolver a partir del startIndex. El parámetro length es opcional y, si no se usa, el método SubString() devolverá todos los caracteres.

Extracción de una Subcadena desde una Posición de Inicio y una Longitud Fija

El código de ejemplo a continuación recupera la parte del valor de cadena $guid que comienza desde el índice 9 y devuelve exactamente los 5 caracteres que le siguen.

$guid = 'e957d74d-fa16-44bc-9d72-4bea54952d8a'
$guid.SubString(9,5)

Extracción de una Subcadena desde una Posición de Inicio Dinámica

Este próximo ejemplo demuestra cómo puede utilizar la propiedad de longitud de cadena de PowerShell para definir dinámicamente un índice de inicio.

El código a continuación hace lo siguiente:

  • Obtiene la longitud del objeto de cadena.
  • Obtiene el índice de la posición media dividiendo la longitud por 2.
  • Utiliza el índice medio como el índice de inicio de la subcadena.
$guid = 'e957d74d-fa16-44bc-9d72-4bea54952d8a'
$guid.SubString([int]($guid.Length/2))

Dado que el valor de length no se especificó, el método Substring() devolvió todos los caracteres desde el índice de inicio.

Extracting a Substring from a Dynamic Starting Position

Comparando Cadenas en PowerShell

Puedes utilizar PowerShell para comparar cadenas también mediante los métodos incorporados del objeto cadena, como CompareTo(), Equals() y Contains(). O utilizando los operadores de comparación de PowerShell.

Utilizando el Método CompareTo()

El método CompareTo() devuelve un valor de 0 si las dos cadenas tienen el mismo valor. Por ejemplo, el código a continuación compara dos objetos de cadena.

$string1 = "This is a string"
$string2 = "This is a string"
$string1.CompareTo($string2)

Y dado que los valores son iguales, el resultado debería ser 0, como se muestra a continuación.

Using CompareTo() method to compare strings

Utilizando el Método Equals() y -eq

El método Equals() y el operador -eq se pueden utilizar para verificar si el valor de las dos cadenas es igual.

El ejemplo a continuación utiliza el método Equals() para comparar los valores de $string1 y $string2.

$string1 = "This is a string"
$string2 = "This is not the same string"
$string1.Equals($string2)

El código anterior debería devolver False porque los valores de $string1 y $string2 no son iguales entre sí.

Comparing strings with the Equals() method

El siguiente ejemplo de código utiliza -eq en su lugar para comparar los valores de $string1 y $string2.

$string1 = "This is a string"
$string2 = "This is not the same string"
$string1 -eq $string2

Como puedes ver en el resultado a continuación, el resultado al usar -eq y el método Equal() son iguales.

Comparing strings with the -eq operator

Usando el Método Contains()

En este ejemplo, las dos cadenas se comparan comprobando si la cadena de PowerShell contiene la subcadena de otra cadena.

El código a continuación muestra que los valores de $string1 y $string2 no son iguales. Sin embargo, el valor de $string2 es una subcadena de $string1.

$string1 = "This is a string 1"
$string2 = "This is a string"
$string1.Contains($string2)

El resultado del código anterior debería ser True, como se muestra a continuación.

Comparing strings using the Contains() method

Lectura Adicional

Source:
https://adamtheautomator.com/powershell-strings/