Saltar a contenido

Tratamiendo Texto

1.Split de una cadena de texto

En este ejemplo vamos a extraer un valor a partir de una URL. Es un buen ejemplo porque las URLs tiene muchos caracteres y es bastante ilustrativo el ejemplo

Tenemos esta URI de git:

git@gitlab.mycompay.com:proyectos/backend/tools/string-utils-lib.git

Imaginemos que hacemos el clone y luego queremos entrar en la carpeta, para ese proceso tenemos que calcular el nombre del directorio creado string-utils-lib .

  1. Vamos a hacer split basandonos en el separador “/” , y nos quedarmemos con el ultimo elemento string-utils-lib.git

La sintaxis es:

#!/bin/bash
arrIN=(${"cadenaDeTexto"//"elementoSeparador"/ })

Escapando caracteres

Si utilizamos como elemento separador / debemos tener en cuenta que lo debemos escapar, asi que nos quedara \/.

Nos queda asi el bash script:

#!/bin/bash
TARGET_REPO_URL=git@gitlab.mycompay.com:proyectos/backend/tools/string-utils-lib.git
arrIN=(${TARGET_REPO_URL//\// })

#Podemos recorrerlo indicando el indice 
PRIMER_ELEMENTO=${arrIN[0]}
echo $PRIMER_ELEMENTO   # git@gitlab.mycompay.com:proyectos
SEGUNDO_ELEMENTO=${arrIN[1]}
echo $SEGUNDO_ELEMENTO  # backend
TERCER_ELEMENTO=${arrIN[1]}
echo $TERCER_ELEMENTO  # tools

2. Elementos del array

Al igual que en la entrada de argumentos a shell script, usamos el caracter ‘@’.

#!/bin/bash
TARGET_REPO_URL=git@gitlab.mycompay.com:proyectos/backend/tools/string-utils-lib.git
arrIN=(${TARGET_REPO_URL//\// })
LONGITUD=${arrIN[@]}
echo "y la longitud es $LONGITUD" # y la longitud es 4

3. Ultimo elemento del array (-1)

El ultimo elemento del array se calcula como indice -1

#!/bin/bash
TARGET_REPO_URL=git@gitlab.mycompay.com:proyectos/backend/tools/string-utils-lib.git
arrIN=(${TARGET_REPO_URL//\// })
ULTIMO_ELEMENTO=${arrIN[-1]}
echo "el ultimo elemento es $ULTIMO_ELEMENTO" # el ultimo elemento es string-utils-lib.git

4. Iterando un array

Ahora que sabemos calcular el tamaño podemos iterarlo de manera sencilla

#!/bin/bash
TARGET_REPO_URL=git@gitlab.mycompay.com:proyectos/backend/tools/string-utils-lib.git
arrIN=(${TARGET_REPO_URL//\// })
LONGITUD=${arrIN[@]}
#Iteramos 
for (( i=0; i<$LONGITUD; i++ )); 
do 
echo "${arrIN[$i]}" ; 
done

# OUTPUT
#git@gitlab.mycompay.com:proyectos
#backend
#tools
#string-utils-lib.git

5.Ejemplo script

Ahora que sabemos splitear, buscar el ultimo elemento(string-utils-lib.git) , vamos a cortarlo por el simbolo “.” para obtener la estructura [“string-utils-lib”, “git”] y nos quedamos con el primer elemento que es el que nos interesa.

En este caso vamos a hacerlo con “cut” Nos queda asi el script completo:

#!/bin/bash
TARGET_REPO_URL=git@gitlab.mycompay.com:proyectos/backend/tools/string-utils-lib.git
# Spliteramos basandonos en el caracter / y obtenemos un array 
arrIN=(${TARGET_REPO_URL//\// })
REPO_NAME=${arrIN[-1]}  # LAST ELEMENT 
echo $REPO_NAME # => string-utils-lib.git
#Cortamos por el caracter "." (-d ".") y nos quedamos con el primer elemento (-f 1)
REPO_NAME=$(echo $REPO_NAME | cut -d "." -f 1)
echo $REPO_NAME  
#output
#string-utils-lib

#Y entramos en el directorio
cd $REPO_NAME 

6.Utilizando SED

Para hacer replaces sencillos de cadenas de textos en ficheros se puede utilizar la herramienta nativa de shell sed.

Imaginemos un fichero en el que queremos cambiar el valor del campo version. Como ese valor queremos reemplazarlo, marcamos el valor con una cadena de texto reconocible , en este caso

/tmp/mifichero.json

{
    "artifactId": "commons-lang3", 
    "groupId": "org.apache.commons",
    "version":"<replaceme>"
}

Ahora construiremos un shell script que cambie ese valor usando sed changeValue.sh

#!/bin/bash
# si se ha pasado un argumento al script ( changeValue.sh 37.1.23 se usara ese valor)
NUEVO_VALOR=$1
if [ "$NUEVO_VALOR" = "" ] ; 
then
    NUEVO_VALOR=3.3.3  # si no se ha pasado ningun argumento se pondra 3.3.3
fi

sed -i "s/<replaceme>/${NUEVO_VALOR}/g" "/tmp/mifichero.json"
El valor en el fichero destino se habra cambiado por
{
    "artifactId": "commons-lang3", 
    "groupId": "org.apache.commons",
    "version":"3.3.3"
}

7.Trabajando con Templates

En el ejemplo anterior, si queremos cambiar el valor de version mas de una vez no podremos, porque en la primera ejecucion cambiamos por 3.3.3 , pero en la segunda ejecucion nuestro sed no encontrara , porque ya tiene otro valor. Para esto es mejor usar templates

Una aproximacion seria genera una carpeta que contenga los ficheros originales (los que siempre contienen )

Y otro directorio donde copiaremos las templates y alli ya haremos el sed.

–templates - mifichero.json - mifichero2.json

–outpudir

Ahora haremos un shell script que 1. Copie las templates en el outputdir (borra si hubiera con anterioridad) 2. Recorra todos los ficheros y haga el replace

changeValue.sh

#!/bin/bash

# si se ha pasado un argumento al script ( changeValue.sh 37.1.23 se usara ese valor)
NUEVO_VALOR=$1
if [ "$NUEVO_VALOR" = "" ] ; 
then
    NUEVO_VALOR=3.3.3  # si no se ha pasado ningun argumento se pondra 3.3.3
fi

####################################
#REMOVE OLD generated files at outputdir
####################################
rm -R $PWD/outputdir
mkdir -p $PWD/outputdir
####################################
# COPY SNIPPETS TEMPLATES TO docs/snippets
####################################
cp -R $PWD/templates $PWD/outputdir

####################################
# REPLACE TEMPLATE VALUES IN FINAL FILES
####################################
foundfilesatDir=$PWD/outputdir
for file in "$foundfilesatDir"/*
do
  echo "$file"
  sed -i "s/<replaceme>/${NUEVO_VALOR}/g" "$file" 
done
Con esto habremos cambiado el valor en todos los ficheros que se generaron a partir de las templates. Y ademas podremos ejecutarlo todas las veces que queramos.

8.Trabajando con envsubst

EnvSubst es una utilidad Unix que nos permite sustituir texto dentro de ficheros por su valor en variables de entorno

Asi imaginemos este fichero index.html.template:

<html>
<body>
    <h1> Welcome to $URL_MODULE </h1>
</body>
</html>

Podemos hacer un script que de valor a esas variables de entorno (en este caso $URL_MODULE).

#!/bin/bash

# Initialization for this module
URL_MODULE="https://mipagina.com"
export URL_MODULE=$URL_MODULE

# INDEX PAGE
cat ./index.html.template | envsubst > ./public/index.html
rm ./public/index.html.template
Vemos que el cat del fichero template, le procesamos con envsubt y el output generamos ya el fichero final.

cat ./index.html.template | envsubst > ./index.html
rm ./index.html.template

cat ./index.html  # Veo que el fichero final tiene el valor sustituido

<html>
<body>
    <h1> Welcome to https://mipagina.com </h1>
</body>
</html>

Conclusion

Hemos visto un ejemplo sencillo de procesamiento de texto y manejo de arrays en BashScript