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.