Manipulación de cadenas

Bash tiene un modesto control de cadenas aunque en muchos scripts puede ser mucho más que interesante y en ocasiones muy útil. En algunos casos se usa opciones internas de Bash y en otras se apoya en el comando externo expr.

Longitud de cadena

nos indica la longitud de una cadena, para ello podemos usar estas formas:

  • ${#cadena}
  • expr length $cadena
  • expr "$cadena" : '.*'
cadena=abcABC123ABCabc
       012345678901234

echo ${#cadena}                 # 15
echo $(expr length $cadena)     # 15
echo $(expr "$cadena" : '.*')   # 15

Posición o indice

nos indica la posición del inicio de una subcadena o carácter, para ello podemos usar estas formas:

  • expr match "$cadena" '$subcadena'
  • expr "$cadena" : '$subcadena'
  • expr index $cadena $subcadena

En las dos primeras $subcadena es una expresión regular y nos muestra el primera posición de dicha expresión. En la tercera la posición mostrada es del primer carácter de $subcadena que aparezca en $cadena.

Aquí tenemos un ejemplo:

cadena=abcABC123ABCabc
        123456789012345

echo `expr match "$cadena" 'abc[A-Z]*.2'`         # 8
echo `expr "$cadena" : 'abc[A-Z]*.2'`             # 8
echo `expr index "$cadena" C12`                   # 6 = posición de C
echo `expr index "$cadena" 1c`                    # 3 = 'c' en 3ra posición antes que '1' = 7.
echo "$cadena" "C12" | awk '{print index($1,$2)}' # 6
echo "$cadena" "1c" | awk '{print index($1,$2)}'  # 0 (no se encuentra la cadena '1c'

Extraer subcadena

nos permite extraer una subcadena de otra cadena, para ello podemos usar estas formas:

  • ${cadena:posicion:longitud}

    extrae los caracteres indicados por longitud de cadena a partir de la posición posicion. Se puede omitir :longitud y entonces extraerá todos los caracteres hasta el final de cadena. También se puede poner una longitud negativa (se debe poner entre paréntesis o un espacio antes del menos) para que se empiece por el final en vez de empezar por el principio.

    Un ejemplo:

    cadena=abcABC123ABCabc
    #      0123456789.....
    # (-)  ....09876543210
    #      Se empieza desde 0.
    
    echo ${cadena:0}       # abcABC123ABCabc
    echo ${cadena:0:1}     # a = primer caracter
    echo ${cadena:7}       # 23ABCabc
    echo ${cadena:7:3}     # 23A = 3 caracteres desde posición 7
    echo ${cadena:7:-3}    # 23ABCabc = desde posición 7 hasta el final
    echo ${cadena:(-4)}    # Cabc
    echo ${cadena: -4}     # Cabc (atención al espacio antes del menos)
    echo ${cadena: -4:2}   # Ca  (atención al espacio antes del menos)
  • expr substr $cadena $posicion $longitud

    Lo mismo que la anterior pero usando expr con la diferencia de que en vez de empezar por 0 se empieza por 1.

  • expr match "$cadena" '\($subcadena\)'

    extrae $subcadena que es una expresión regular del principio de $cadena. Con un ejemplo se ve mejor:

    cadena=abcABC123ABCabc
    #      =======
    
    echo $(expr match "$cadena" '\(.[b-c]*[A-Z]..[0-9]\)')   # abcABC1
    echo $(expr "$cadena" : '\(.[b-c]*[A-Z]..[0-9]\)')       # abcABC1
    echo $(expr "$cadena" : '\(.......\)')                   # abcABC1
    
  • expr "$cadena" : '\($subcadena\)'

    otra forma de expresar lo mismo que la anterior.

  • expr match "$cadena" '.*\($subcadena\)'

    extrae $subcadena que es una expresión regular del final de $cadena. Con un ejemplo se ve mejor:

    cadena=abcABC123ABCabc
    #               ======
    
    echo $(expr match "$cadena" '.*\([A-C][A-C][A-C][a-c]*\)')    # ABCabc
    echo $(expr "$cadena" : '.*\(......\)')                       # ABCabc
    
  • expr "$cadena" : '.*\($subcadena\)'

    otra forma de expresar lo mismo que la anterior.

Borrar subcadena

diferentes formas de borrar subcadenas de una cadena:

  • ${cadena#subcadena}

    borra la coincidencia más corta de subcadena desde el principio de cadena (ver ejemplo en el siguiente)

  • ${cadena##subcadena}

    borra la coincidencia más larga de subcadena desde el principio de cadena. un ejemplo:

    cadena=abcABC123ABCabc
    #      |----|          mas corta
    #      |----------|    mas larga
    
    echo ${cadena#a*C}      # 123ABCabc
    # Extrae la coincidencia mas corta entre 'a' y 'C'.
    
    echo ${cadena##a*C}     # abc
    # Extrae la coincidencia mas larga entre 'a' y 'C'.
    
  • ${cadena%subcadena}

    borra la coincidencia más corta de subcadena desde el final de cadena (ver ejemplo en el siguiente)

  • ${cadena%%subcadena}

    borra la coincidencia más larga de subcadena desde el final de cadena. un ejemplo:

    cadena=abcABC123ABCabc
    #                   ||     mas corta
    #       |------------|     mas larga
    
    echo ${cadena%b*c}      # abcABC123ABCa
    # Extrae la coincidencia mas corta entre 'b' y 'c', desde el final de cadena.
    
    echo ${cadena%%b*c}     # a
    # Extrae la coincidencia mas larga entre 'b' y 'c', desde el final de cadena.
    

Reemplazar subcadena

diferentes formas de reemplazar subcadenas de una cadena:

  • ${cadena/buscar/reemplzar}

    Reemplaza la primera coincidencia de buscar con reemplzar (ver ejemplo en la siguiente)

  • ${cadena//buscar/reemplzar}

    Reemplaza todas las coincidencias de buscar con reemplzar. un ejemplo:

    cadena=abcABC123ABCabc
    
    echo ${cadena/abc/xyz}      # xyzABC123ABCabc
    # Reemplaza la primera coincidencia de 'abc' con 'xyz'.
    
    echo ${cadena//abc/xyz}     # xyzABC123ABCxyz
    # Reemplaza todas las coincidencias de 'abc' con 'xyz'.
    
  • ${cadena/#buscar/reemplzar}

    Si buscar coincide con el principio de cadena, entonces sustituye buscar por reemplazar.

  • ${cadena/%buscar/reemplzar}

    Si buscar coincide con el final de cadena, entonces sustituye buscar por reemplazar.

    cadena=abcABC123ABCabc
    
    echo ${cadena/#abc/XYZ}     # XYZABC123ABCabc
    echo ${cadena/%abc/XYZ}     # abcABC123ABCXYZ
    

Mayúsculas / Minúsclas

Manipular Mayúsculas y Minúsculas

  • ${cadena^}

    Capitaliza el primer carater de cadena

    cadena=AbcAbC123ABCaBc
    echo ${cadena^^}         # AbcAbC123ABCaBc
    
  • ${cadena^^}

    Pone todos los caracteres de cadena a mayúsculas

    cadena=AbcAbC123ABCaBc
    echo ${cadena^^}         # ABCABC123ABCABC
    
  • ${cadena,}

    Pone en minúsculas el primer carater de cadena

    cadena=AbcAbC123ABCaBc
    echo ${cadena,}         # abcAbC123ABCaBc
    
  • ${cadena^^}

    Pone todos los caracteres de cadena a minúsculas

    cadena=AbcAbC123ABCaBc
    echo ${cadena,,}         # abcabc123abcabc
    

Saber si una cadena contiene una subcadena

Podemos necesitar saber si una subcadena está en una cadena, algo de tipo "si subcadena está en cadena entonces" y en Bash tenemos una forma muy sencilla:

cadena='una frase de texto cualquiera larga'
subcadena="cual"

if [[ "$cadena" == *"$subcadena"* ]]
then
  echo "Si hay '$subcadena' en '$cadena'";
fi

Retro

Lugares

Redes

Sistemas

Varios