Aprende a realizar el cálculo de la letra del DNI mediante un script Bash
Tras satisfacer los requisitos para poder ejecutar los scripts Bash, y comprender cómo definir funciones, aprende cómo devolver valores en funciones Bash. Para ello vamos a crear un pequeño ―pero potente― programa en Bash que calcule las letras de los DNI. Tengo buenas noticias: Bash también puede ser instalado en Windows 10. Con lo que puede ser añadida toda la potencia de Linux en sistemas operativos, digamos… distintos.
Antes que nada, tendemos que comprender cómo funcionan los substrings, que como en cualquier lenguaje, posee la posibilidad de devolver partes de una cadena a partir de la indicación de la cadena, la posición y la longitud del segmento. Veamos un ejemplo de este comportamiento. Creamos nuestro script con
$ touch prueba_substring $
Luego añadimos el siguiente código con vuestro editor preferido. En modo terminal mi editor preferido es mcedit. Pero últimamente veo que nano está tomando fuerza.
#!/usr/bin/env bash # Demo comportamiento de substrings en Bash # Pedro Ruiz Hidalgo # version 1.0.0 # Febrero 2017 ret="\n" CADENA="siempre uso Linux con Ubuntu y Ubunlog, claro!" # "0123456789012345678901234567890123456789012345" # " 1 2 3 4 " # (usa la regla para medir los caracteres) echo -e $ret ${CADENA:12} echo -e $ret ${CADENA:12:5} echo -e $ret "Aprendo en ${CADENA:31:7}" exit 0
Añadiendo los permisos y ejecutando así:
$ chmod +x prueba_substring $ ./prueba_substring $
Debería, si todo ha ido bien, arrojar el siguiente resultado:
Linux Con Ubuntu y Ubunlog, claro! Linux Aprendo en Ubunlog
Funcionamiento de las subcadenas
Como podéis observar arriba he resaltado las lineas 13 a la 15 del script y paso a explicar su código. Echo con el parámetro «-e» permite mostrar el caracter siguiente línea, este carácter lo hemos definido en la línea 7 y asignado a la variable «ret».
Linea 13: Muestro la subcadena (substring) de la variable CADENA, descrita en la línea 8, a partir de la posición 12. Siempre empezando a contar desde la posición 0.
Linea 14: A partir de la posición 12 de la variable CADENA, muestro un segmento de 5. Como comprobaréis esto corresponde a la subcadena “Linux”.
Linea 15: Compongo una nueva cadena encerrada entre comillas que comienzo como “Aprendo en “, para continuar con una subcadena de la variable CADENA desde la posición 31, tomando un segmento de 7: esto corresponde a “Ubunlog”.
Funciones con devolución de datos
El mecanismo de devolución de datos con Bash se produce mediante la orden “return”, si bien, cuando renemos que igualarlo a una variable Bash implementa un mecanismo «extraño», al que hay que acostumbrarse. Veamos el siguiente ejemplo:
#!/usr/bin/env bash function suma(){ local a=$1 local b=$2 return $(( $a + $b )) } suma 12 23 retorno=$? echo $retorno
Las funciones siempre han de ser definidas antes de usarlas en Bash, por tanto, tras la shebang declaramos la función suma, en la línea 4 definimos mediante “local” la asignación del primero de los parámetros ($1) a la variable «a». Idéntico procedimiento en la línea 5, donde asignamos el segundo parámetro a ($2) a la variable «b». En la línea nueve llamamos a la función suma con dos parámetros que se convertirán por el mecanismo descrito en las variables «a» y «b» y con «return» los devolvemos sumado, como fácilmente puede observarse en la instrucciones de la función.
Asignamos a la variable «retorno» en la línea 10 el resultado de la ejecución de la función suma.
Tras el estudio y comprensión del la forma en la que se practican las devoluciones de valores y asignación a las variables pasemos a ver nuestro programa del cálculo de letras de DNI con Bash.
Script para el cálculo de letras de DNI con Bash
#!/usr/bin/env bash nl="\n" LETRAS="TRWAGMYFPDXBNJZSQVHLCKEO" NORMAL=0 ERROR=66 if [ $# -lt 1 ]; then echo -e "$nl Cálculo DNI, introduce número$nl" read -r ndni [ -z "${ndni//[0-9]}" ] && [ -n "$ndni" ] || echo "Sólo números" && exit $ERROR else ndni=$1 fi modulo () { return $(( $ndni % 23 )) } modulo ndni mod=$? echo $ndni-${LETRAS:$mod:1} exit $NORMAL
La letra de nuestro DNI corresponde al módulo 23 del número. Esto es, dividimos el número entre 23 y en vez de observar el cociente, observamos el resto de la división. El otras palabras, como los números divisibles por 23 darán cero, la letra que le corresponde es la “T”, ya que esta es la posición 0, como hemos visto en el script de arriba, todas las subcadenas empiezan a contar desde cero. Es decir, con el módulo vamos a obtener siempre números entre 0 (letra “T”) y 22 (letra “O”). En Bash, como en otros lenguajes se obtiene el módulo mediante el operador porciento “%”.
En la linea 5 definimos las letras en su orden. Es obvio, no se puede cambiar el orden para obtener resultados fiables. En el if de la línea 9 estamos preguntando si al llamar al script había un número como parámetro. En caso de no existir parámetro lo solicitamos por teclado con las instrucciones de las líneas 11 a 13. Si el script fue llamado con un número para calcular la orden en la linea 15 asigna este parámetro a la variable «ndni».
En la línea 23 hacemos referencia a la función módulo mediante el parámetro de variable «ndni», bien haya sido recogido como parámetro en bash, o por teclado como entrada. En la línea 24 se asigna la devolución de la función a la variable «mod». En la linea 25 mostramos el número, un guión y la letra correspondiente a la posición según el cálculo del módulo y la subcadena.
Probando nuestro scritp de DNI
$ ./dni 12345678 12345678-Z
O bien,
$ ./dni Cálculo DNI, Introduce número
Todos nuestros scripts deberían incluir un parámetro «-a» para el autor y otro «-h» para la ayuda y sintaxis. Como esto lo hemos visto en anteriores artículos o lo dejo a vosotros para no hacer el código más farragoso.
Espero y deseo que este artículo haya sido de vuestro interés.
El artículo Aprende a realizar el cálculo de la letra del DNI mediante un script Bash ha sido originalmente publicado en Ubunlog.