jueves, 2 de julio de 2009

[HowTo] Extraer líneas en blanco de un fichero en bash

También publicado en universo emergya.

En ocasiones nos puede hacer falta quitar las líneas en blanco de un fichero, buscando por internet, encontré dos formas, una con sed y otra con awk y gracias a mi amigo y compañero de trabajo rcmorano, una tercera con grep. Vamos a ello:

En primer lugar vamos a crear un fichero que cumpla las carácterísticas necesarias para hacer las pruebas llamado "fichero" en /tmp. Podemos copiar el que pongo a continuación:


Linea 1
Linea 2

Linea 4

Linea 6
Linea 7


Linea 10


Notesé que las líneas en blanco se cuentan, es decir las líneas 3, 5, 8 y 9 están en blanco (salto de línea).

Con el comando sed: sed '/^[ ]*$/d' /ruta/al/fichero


$ sed '/^[ ]*$/d' /tmp/fichero
Linea 1
Linea 2
Linea 4
Linea 6
Linea 7
Linea 10


Con el comando awk: awk 'NF' /ruta/al/fichero


$ awk 'NF' /tmp/fichero
Linea 1
Linea 2
Linea 4
Linea 6
Linea 7
Linea 10


Con el comando grep: grep -v ^$ /ruta/al/fichero


$ grep -v ^$ /tmp/fichero
Linea 1
Linea 2
Linea 4
Linea 6
Linea 7
Linea 10


Como podemos comprobar en de las tres formas se omiten las líneas 3, 5, 8 y 9 que son las que están en blanco.

[HowTo] Condiciones múltiples en bash.

Esta segunda entrada tambíen la tengo publicada en universo emergya.

Aunque parezca una chorrada, cada vez que he tenido que hacer un script en bash y me ha hecho falta comprobar más de una condición, he perdido algún tiempo hasta averiguar cómo se hace. Finalmente el man test me dio la respuesta, pero por si alguien a alguien le da pereza verlo, dejo aqui cómo se hace.

Da igual el tipo de estructura: if, while, etc.

Ejemplo de AND.


if [ "$VARIABLE1" = "OK" -a "$VARIABLE2" = "FAIL" -a $VARIABLE3 -lt 5 ]; then
acción1
acción2
fi


En este caso si VARIABLE1 es igual a OK y VARIABLE2 es igual a FAIL y la VARIABLE3 es menor que 5 entonces hace las acciones. En caso de no cumplir todas las condiciones no entra y continúa el script.

Ejemplo de OR.


CONTADOR=0
while [ "$VARIABLE" = "FAIL" -o $CONTADOR -lt 10 ]; do
acción1
accion2
CONTADOR=$(($CONTADOR+1))
done


En este caso, mientras VARIABLE se igual a FAIL o CONTADOR menor que 10 entrará en el bucle, es decir, realizará las acciones si cumple alguna de las dos condiciones.

También se pueden combinar AND (-a) con OR (-o) para hacer lo que queramos. Eso es todo, espero os resulte de utilidad.

[HowTo] Operaciones aritméticas en bash

LLevo algún tiempo sin escribir en el blog, y tengo un par de entradas que he publicado en otro sitio (universo emergya) y me gustaría tenerlas en mi blog, no porque no haya "literatura" en google al respecto, sino para futuras consultas. En concreto son dos pequeñas pinceladas de bash script que me han hecho falta recientemente. En esta entrada está la primera de ellas: Operaciones aritméticas básicas en bash.

Las formas más conocidas para realizar operaciones aritméticas con bash son mediante los comandos let y expr. Ambas expresiones pueden ser un tanto "pijoteras" en cuanto a sintaxis y el otro día trasteando por ahí encontré una forma a mi juicio bastante más sencilla.

Forma tradicional con let editamos un fichero llamado prueba1 con algún editor de texto:

#!/bin/bash

CONTADOR=0
while [ $CONTADOR -lt 10 ]; do
echo "Contador vale: $CONTADOR"
let "CONTADOR += 1"
done


Ejecutamos prueba1

$ chmod +x prueba1
$ ./prueba1
Contador vale: 0
Contador vale: 1
Contador vale: 2
Contador vale: 3
Contador vale: 4
Contador vale: 5
Contador vale: 6
Contador vale: 7
Contador vale: 8
Contador vale: 9


En la expresión superior, se inicializa CONTADOR a 0, y mientras contador sea menor que 10, se imprime "Contador vale: " y lo que valga la variable en cada nueva entrada del bucle. Tras imprimir el valor, mediante let le suma una unidad a la variable CONTADOR (la expresión con let, significa CONTADOR = CONTADOR + 1) aunque matemáticamente se lea como algo imposible puesto que sería X = X + 1, el '=' no hay que leerlo como una igualdad, sino como una asignación, es decir, se le asigna a lo que se sitúa a la izquierda del '=' lo que hay a la derecha de este. En este tipo de expresiones, primero se calcula lo que hay a la derecha para asignárselo a la variable que hay a la izquierda. El con el comando anterior (chmod) le damos permisos de ejecución al script.

Con expr: prueba2:


#!/bin/bash

CONTADOR=0
while [ $CONTADOR -lt 10 ]; do
echo "Contador vale = $CONTADOR"
CONTADOR=$(expr $CONTADOR + 1)
done


La ejecución producirá una salida idéntica a la anterior, pero esta vez en lugar de usar let hemos usado expr:


$ chmod +x prueba2
$ ./prueba2
Contador vale = 0
Contador vale = 1
Contador vale = 2
Contador vale = 3
Contador vale = 4
Contador vale = 5
Contador vale = 6
Contador vale = 7
Contador vale = 8
Contador vale = 9


Forma alternativa: prueba3


#!/bin/bash

CONTADOR=0
while [ $CONTADOR -lt 10 ]; do
echo "Contador vale = $CONTADOR"
CONTADOR=$((CONTADOR + 1))
done


Como vemos, la ejecución de este script produce la misma salida que los anteriores, pero no se está usando ni let ni expr para hayar la suma de CONTADOR:


$ chmod +x prueba3
$ ./prueba3
Contador vale = 0
Contador vale = 1
Contador vale = 2
Contador vale = 3
Contador vale = 4
Contador vale = 5
Contador vale = 6
Contador vale = 7
Contador vale = 8
Contador vale = 9


Esta última forma, permite usar '$' o no dentro de la expresión para la obtener el valor de la variable.
También se puede poner sin espacios, es decir, el siguiente script también es correcto: prueba3-b


#!/bin/bash

CONTADOR=0
while [ $CONTADOR -lt 10 ]; do
echo "Contador vale = $CONTADOR"
CONTADOR=$(($CONTADOR+1))
done


y devolverá lo mismo que los anteriores:


$ chmod +x prueba3-b
$ ./prueba3-b
Contador vale = 0
Contador vale = 1
Contador vale = 2
Contador vale = 3
Contador vale = 4
Contador vale = 5
Contador vale = 6
Contador vale = 7
Contador vale = 8
Contador vale = 9


Por último señalar que también permite el uso de otros operadores como son división, módulo (resto de la división) y potencia:


#!/bin/bash

CONTADOR=4
echo "Inicalizamos contador = $CONTADOR"

CONTADOR=$((CONTADOR**5))
echo "Contador elevado a la quinta, 4 elevado a 5 = $CONTADOR"

CONTADOR=$((CONTADOR%5))
echo "Resto de dividir el contador por 5 = $CONTADOR"

CONTADOR=$((9/3))
echo "Contador es igual a resultado de la división 9/3 = $CONTADOR"



Este script si lo ejecutamos devolvería:


$ chmod +x prueba
$ ./prueba
Inicalizamos contador = 4
Contador elevado a la quinta, 4 elevado a 5 = 1024
Resto de dividir el contador por 5 = 4
Contador es igual a resultado de la división 9/3 = 3


Personalmente esta forma de hacer operaciones en bash, me parece más legible, con menos texto que las anteriores, y más fácil de recordar la sintaxis por lo que es la que uso actualmente.