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.
nos indica la longitud de una cadena, para ello podemos usar estas formas:
cadena=abcABC123ABCabc 012345678901234 echo ${#cadena} # 15 echo $(expr length $cadena) # 15 echo $(expr "$cadena" : '.*') # 15
nos indica la posición del inicio de una subcadena o carácter, para ello podemos usar estas formas:
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'
nos permite extraer una subcadena de otra cadena, para ello podemos usar estas formas:
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)
Lo mismo que la anterior pero usando expr con la diferencia de que en vez de empezar por 0 se empieza por 1.
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
otra forma de expresar lo mismo que la anterior.
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
otra forma de expresar lo mismo que la anterior.
diferentes formas de borrar subcadenas de una cadena:
borra la coincidencia más corta de subcadena desde el principio de cadena (ver ejemplo en el siguiente)
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'.
borra la coincidencia más corta de subcadena desde el final de cadena (ver ejemplo en el siguiente)
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.
diferentes formas de reemplazar subcadenas de una cadena:
Reemplaza la primera coincidencia de buscar con reemplzar (ver ejemplo en la siguiente)
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'.
Si buscar coincide con el principio de cadena, entonces sustituye buscar por reemplazar.
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
Manipular Mayúsculas y Minúsculas
Capitaliza el primer carater de cadena
cadena=AbcAbC123ABCaBc echo ${cadena^^} # AbcAbC123ABCaBc
Pone todos los caracteres de cadena a mayúsculas
cadena=AbcAbC123ABCaBc echo ${cadena^^} # ABCABC123ABCABC
Pone en minúsculas el primer carater de cadena
cadena=AbcAbC123ABCaBc echo ${cadena,} # abcAbC123ABCaBc
Pone todos los caracteres de cadena a minúsculas
cadena=AbcAbC123ABCaBc echo ${cadena,,} # abcabc123abcabc
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