A veces se encuentran ciertas limitaciones a la hora de escribir scripts de shell en el manejo de cadenas y es que, muchas veces, nos olvidamos de que bash tiene un montón de operaciones sobre strings. Por ejemplo:
Shell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# Cadena de ejemplo:
string=123.abc.456.ABC.123
# Ver la longitud de la cadena
$echo${#string}
19
# Extraer subcadena desde una posicion
$echo${string:4}
abc.456.ABC.123
# Extraer subcadena de longitud determinada
# desde una posicion
$echo${string:4:7}
abc.456
# Eliminar la cadena coincidente del principio de la cadena
$echo${string#123}
.abc.456.ABC.123
# Eliminar la cadena coincidente del final de la cadena
$echo${string%123}
123.abc.456.ABC.
# Reemplazar la primera aparación de una subcadena en la cadena
$echo${string/123/QWE}
QWE.abc.456.ABC.123
# Reemplazar todas las apariciones de una subcadena en la cadena
$echo${string//123/QWE}
QWE.abc.456.ABC.QWE
# Reemplazar si hay coincidencia al pricipio o al final de la cadena:
$echo${string/#123/QWE}
QWE.abc.456.ABC.123
$echo${string/%123/QWE}
123.abc.456.ABC.QWE
# Longitud de la coincidencia al principio de la cadena (dos formas)
$exprmatch"$string"'123'
3
$expr"$string":'123'
3
Otra cuestión donde no es difícil cometer errores es en las comparaciones; al no ser bash un lenguaje tipado, ciertas construcciones pueden dar lugar a errores que pasan desapercibidos y llegan a ser difíciles de detectar. Así que recordemos:
El operador de comparación es =, no -eq.
== es sinónimo de =
El operador “distinto de” es !=
Ejemplos:
Shell
1
2
3
4
5
6
7
8
9
10
11
12
13
$$a=foo
$$b=bar
$["$a"="$b"]&&echo'las dos variables son iguales'||echo'las dos variables son distintas'
las dos variables son distintas
$["$a"="$b"]&&echo'las dos variables son iguales'||echo'las dos variables son distintas'
las dos variables son iguales
$["$a"=="$b"]&&echo'las dos variables son iguales'||echo'las dos variables son distintas'
las dos variables son distintas
$if["$a"!="$b"];thenecho"Las dos variables son distintas";fi
Las dos variables son distintas
Pero, con dobles corchetes, el funcionamiento es distinto (pattern matching):
Shell
1
2
3
$filename=foto.jpg
$if[["$filename"!=*.gif]];thenecho"El fichero no parece un gif";fi
El fichero no parece un gif
Si las expresiones son compuestas, se pueden usar los operadores -a (y lógico) y -o (o lógico). Y, sólo en el caso de usar dobles corchetes, sus “casi” equivalentes && y || o
Si tenemos ficheros de plantillas en los que hemos definido algunas variables y queremos obtener el fichero tras aplicar la sustitución de las variables, podriamos emplear el comando “eval” de la siguiente manera.
Shell
1
eval"echo \"$(cat /ruta/a/la/plantilla)\""
Por ejemplo, podriamos tener un fichero de plantilla llamado “saludo.txt”
Hola $NOMBRE, estamos muy agradecidos de que lea el Blog $BLOG
Ahora desde un script de shell podriamos leer este fichero y aplicar una sutitucion de variables de una manera similar a la siguiente:
Shell
1
2
3
NOMBRE="John Doe"
BLOG="Ubuntulife.net"
eval"echo \"$(cat ./saludo.txt)\""
Si no lo conociais el comando “eval” nos puede servir por ejemplo para evaluar una expresión de cadena y proceder a su ejecución en la shell, por ejemplo:
eval “ls -l” nos saca un listado de los archivos.
Pero como eval parte de una expresion construida a base de strings, ya os podeis imaginar que puede hacer bastantes cosas interesantes en la programación de bash.
Podemos hacer bucles que recorran los argumentos de entrada de nuestro programa, por ejemplo:
Shell
1
2
3
4
5
6
7
#!/bin/bash
CONTADOR=0
foriin"$@"
do
let CONTADOR=$CONTADOR+1
echo"Argumento $CONTADOR: $i"
done
La parte del contador no es estrictamente necesaria, pero da un toque de distinción. Desde aquí hemos recorrido todos los argumentos del programa, ya podremos procesarlos como queramos, o si son archivos de entrada, abrirlos, etc.
Pero también podemos hacerlo de otra forma, que nos puede resultar más cómoda en otras ocasiones, con un bucle while:
¿Te ha servido este sitio alguna vez? Cada script, cada línea de ayuda aquí es fruto de horas de trabajo y pasión por compartir. Si alguna vez resolviste un problema gracias a esta página, considera hacer una donación. Tu aporte —por pequeño que sea— mantiene vivo este proyecto y me impulsa a seguir creando.