Dividir cadena en variables en Bash

Abdul Mateen 20 junio 2023
  1. Cuerdas en Bash
  2. Funciones de cadena en Bash
  3. Dividir cadena en variables en Bash
  4. Use el comando cortar para dividir cadenas en variables en Bash
  5. Use un separador de campo interno (IFS) para dividir cadenas en variables en Bash
  6. Use leer con sed para dividir cadenas en variables en Bash
  7. Use una expresión regular con coincidencia para dividir cadenas en variables en Bash
Dividir cadena en variables en Bash

Este tutorial discutirá diferentes métodos para dividir una cadena en variables en Bash.

Comenzaremos nuestra discusión con una breve introducción a las cadenas. Más adelante, discutiremos varias formas de dividir cadenas usando ejemplos de Bash.

Cuerdas en Bash

Una cadena es una combinación/colección de caracteres. En Bash, una cadena es un tipo de datos como un entero o un flotante.

Los caracteres también pueden incluir dígitos, ya que vemos números dentro de una cadena como una secuencia de caracteres ASCII.

En tipos de datos como enteros o flotantes, el número es una entidad completa; no hay existencia individual de dígitos. Sin embargo, en una cadena, cada carácter dentro de la cadena (incluidos el espacio, la coma, el punto y coma y los dos puntos) tiene su representación.

En combinación, los caracteres individuales también representan una cadena completa. Cualquier carácter que pueda escribir desde el teclado puede ser parte de la cadena.

Por ejemplo:

s1="Welcome"
s2="This is a complete sentence and string as well"
s3="The string, has some special charactrs like ,$%^[]"
s4="The population of country ABC is 12345678"

Aquí, la primera cadena solo tiene letras. La siguiente cadena (es decir, s2) también tiene espacios; estos espacios son parte de la cadena y se almacenarán como alfabetos.

Por lo tanto, en la segunda cadena hay ocho espacios, que ocuparán ocho bytes en la memoria.

La tercera cadena tiene caracteres especiales, que nuevamente forman parte de la cadena.

Por último, en la cuarta cadena tenemos un número, no un número sino una combinación de dígitos. Si desea realizar un cálculo/comparación como un número, es imposible a menos que se convierta en un número a través de algún mecanismo.

Funciones de cadena en Bash

Al igual que las operaciones aritméticas con números enteros o de punto flotante, ciertas operaciones/funciones son posibles/disponibles con cadenas.

Por ejemplo, podemos comparar la igualdad de dos cadenas (se requiere la operación de igualdad si tenemos que encontrar una cadena o una subcadena). Aquí está el script de Bash:

s1="World Cup."
s2="World Cup"

if [ "$s1" = "$s2" ]; then
    echo "Strings are equal."
else
    echo "Strings are not equal."
fi

s3="World Cup."

if [ "$s1" = "$s3" ];  then
    echo "Both the strings are equal."
else
    echo "Strings are not equal."
fi

Aquí, tenemos dos cadenas que se ven iguales; sin embargo, hay una diferencia en el punto al final de la primera cadena.

La secuencia de comandos anterior primero compara las dos cadenas mediante una declaración if, donde las variables de cadena se escriben entre comillas dobles y se utiliza un solo signo igual para comparar.

A continuación, declara otra cadena, s3, igual que la primera cadena, y vuelve a realizar una comparación. La salida de este script es:

Strings are not equal.
Both the strings are equal.

Podemos encontrar la longitud de una cadena usando un signo hash. El guión de Bash es:

s=abcAXYZ123456_AaBbCc
echo "Length of " $s " is:" ${#s}

La salida de este script es:

Length of abcAXYZ123456_AaBbCc is: 20

Podemos comparar y obtener la longitud de la subcadena usando expresiones regulares (no entraremos en detalles de una expresión regular, puede leer sobre expresiones regulares aquí).

Aquí está el código para hacer coincidir usando una expresión regular:

s=abcAXYZ123456_AaBbCc
echo `expr match "$s" 'abc[A-Z]*.2'`
echo `expr "$s" : 'abc[A-Z]*.[0-9]*_'`

En la primera coincidencia, estamos emparejando un abc pequeño, seguido de letras mayúsculas (cero o más), seguidas del dígito 2.

El segundo partido utiliza una forma ligeramente diferente. Sin embargo, hacer coincidir la subcadena cerrada con un guión bajo usando una expresión regular.

La salida del script anterior es:

9
14

En la primera coincidencia, el dígito 2 viene en la posición 9, y en la segunda coincidencia, el guión bajo está en la posición 14. Hay una larga lista de operaciones/funciones posibles en las cadenas.

En la primera coincidencia, el dígito dos viene en la posición 9. En la segunda coincidencia, el guión bajo viene en la posición 14.

Sin embargo, nos estamos moviendo hacia nuestro tema principal, dividir una cadena.

Dividir cadena en variables en Bash

Dividir una cadena en caracteres o subcadenas es una operación común y de uso frecuente. Por ejemplo, se requiere una división de expresiones en variables y operadores (conocidos como tokens) antes de que pueda evaluarse.

Antes de comenzar la fase de traducción, los compiladores o traductores de otros idiomas utilizan analizadores léxicos para analizar y dividir un programa, una cadena, en variables, palabras clave, bloques, funciones, etc. En el procesamiento del lenguaje natural, la división de un artículo en oraciones, palabras, verbos, sustantivos, etc., es obligatorio.

Hay diferentes formas en Bash para dividir una cadena. Los discutiremos con ejemplos.

Use el comando cortar para dividir cadenas en variables en Bash

En Bash, podemos usar la operación cortar para dividir una cadena. La sintaxis del comando cortar es:

cut -f(number) -d(delimiter)

El comando cortar divide una cadena según el delimitador proporcionado después de la opción -d. El delimitador en las cadenas puede ser cualquier carácter que separe (o se suponga que separa) dos subcadenas.

Por ejemplo, en el idioma inglés, las oraciones están separadas por un punto; por lo tanto, un punto puede considerarse como un delimitador para separar oraciones. De manera similar, el espacio es un delimitador para separar palabras.

Un operador es un delimitador entre operandos en una expresión aritmética (en programación).

A continuación, tenemos un script donde tenemos una cadena con un guión como delimitador. La cadena se divide en tres variables.

Cuando usamos una variable por primera vez, no se requiere un signo de dólar; sin embargo, las operaciones posteriores requieren un signo de dólar con variables. El guion es:

v="0123-456-789"
v1=$(echo $v | cut -f1 -d-)
v2=$(echo $v | cut -f2 -d-)
v3=$(echo $v | cut -f3 -d-)
echo $v1
echo $v2
echo $v3

La salida de este script es:

0123
456
789

Usaremos otro delimitador con una operación de corte para darle una idea. Aquí hay otra secuencia de comandos con dos puntos como delimitador:

v="0123:456:789"
v1=$(echo $v | cut -f1 -d:)
v2=$(echo $v | cut -f2 -d:)
v3=$(echo $v | cut -f3 -d:)
echo $v1
echo $v2
echo $v3

El código es el mismo excepto por el delimitador. Los dos puntos son un delimitador en la cadena; el mismo se utiliza en la operación de corte.

La salida de este script es:

0123
456
789

La operación cortar tiene la opción de un solo delimitador; sin embargo, al usar un separador de campo interno, podemos usar múltiples delimitadores.

Use un separador de campo interno (IFS) para dividir cadenas en variables en Bash

Usando IFS, podemos usar delimitadores únicos o múltiples. En el caso de un solo delimitador, no se requieren comillas; sin embargo, para usar varios delimitadores, las comillas dobles pueden contener más de un carácter delimitador.

Veamos un ejemplo muy básico:

IFS=- read v1 v2 v3 v4 <<< this-is-batch-file
echo $v1
echo $v2
echo $v3
echo $v4

En el script anterior, el IFS tiene un solo delimitador. Usando IFS, lea la asignación de la cadena this-is-batch-file a las variables v1 a v4.

La salida de este script es:

this
is
batch
file

A continuación, tenemos un ejemplo de delimitadores múltiples. Vea el siguiente guión:

IFS=" ,: " read v1 v2 v3 v4 <<< is,something,strange:there
echo $v1
echo $v2
echo $v3
echo $v4

Aquí, se usan dos delimitadores en IFS, y la cadena también contiene dos delimitadores. Las tres primeras palabras se separan con una coma y la última palabra se separa con dos puntos.

La salida es:

is
something
strange
there

Ahora usando IFS, tenemos la opción de múltiples delimitadores.

¿Siempre necesitamos dar un delimitador para dividir la cadena? La respuesta es no; tenemos otras formas también.

Use leer con sed para dividir cadenas en variables en Bash

Podemos dividir una cadena en una matriz de caracteres usando read y sed (un comando especial que puede realizar muchas operaciones de cadena línea por línea). Entonces, una vez que tenemos una variedad de caracteres, podemos manipularlos de acuerdo con nuestros requisitos específicos.

Aquí está el guión:

read -ra var5 <<<"$(echo "12-34-56" | sed 's/./& /g')"
echo ${var5[0]}
echo ${var5[1]}
echo ${var5[2]}
echo ${var5[3]}

La salida de este script es:

1
2
-
3

Tenga en cuenta que incluso un carácter de guión se coloca como un carácter; por lo tanto, este método no puede dividir la cadena en ningún delimitador. En su lugar, divide la cadena en una matriz de caracteres.

Hay una excepción a este método. Si usa espacio entre los caracteres, el proceso ignorará el espacio y la matriz resultante no tendrá espacios.

Entendamos esto usando el siguiente script y la Salida adyacente:

read -ra var51 <<<"$(echo "FG HI JK" | sed 's/./& /g')"
echo ${var51[0]}
echo ${var51[1]}
echo ${var51[2]}
echo ${var51[3]}

La salida es:

F
G
H
I

En la salida, es evidente que el subíndice/índice 2 contiene la letra H en lugar de un carácter de espacio.

Use una expresión regular con coincidencia para dividir cadenas en variables en Bash

Ya hemos compartido un enlace para leer sobre expresiones regulares. Aquí, tenemos otra forma de dividir cadenas, usando una expresión regular y una operación de coincidencia usando =~.

El guion es:

re="^([^-]+)-(.*)$"
[[ "31-28-31" =~ $re ]] && var6="${BASH_REMATCH[1]}" && var_r="${BASH_REMATCH[2]}"
[[ $var_r =~ $re ]] && var7="${BASH_REMATCH[1]}" && var8="${BASH_REMATCH[2]}"
echo "First:" $var6
echo "Second:" $var7
echo "Third:" $var8

Nuevamente se usa un guión como delimitador, y nuestra expresión regular contiene un guión. La salida es:

First: 31
Second: 28
Third: 31

A continuación, tenemos el mismo método con una coma delimitadora diferente. El guion es:

re1="^([^,]+),(.*)$"
[[ "high,risk" =~ $re1 ]] && v1="${BASH_REMATCH[1]}" && v2="${BASH_REMATCH[2]}"
echo "First:" $v1
echo "Second:" $v2

La salida es:

First: high
Second: risk

Finalmente, hemos presentado diferentes formas en Bash para dividir la cadena y almacenarla en variables. Ahora, los lectores pueden utilizar el método que mejor se adapte a sus necesidades.

Artículo relacionado - Bash String