next up previous
Next: Filtros - Avanzados Up: Curso de GNU/Linux para Previous: Scripts de Shell -

Subsecciones

Filtros - Básicos

Existen una gran variedad de programas que reciben una entrada, la procesan y emiten una salida, a este tipo de programas le llamamos filtros. Estos son una parte fundamental del sistema ya que relacionando filtros simples se puede conseguir prácticamente cualquier cosa, a nivel de administración de archivos y scripts..

Entre estos filtros están:

cat para mostrar la entrada.
grep, tail, head y cut para seleccionar una parte de la entrada.
less y more para paginar la entrada.
sort para ordenar la entrada
tr para alterar la entrada en forma ordenada.
comm y diff para comparar dos entradas.
wc para contar la entrada.

grep

Un comando muy útil que nos proporciona UNIX es grep. Su función principal es imprimir por pantalla solamente las líneas que concuerden con un patrón que nosotros le indicamos.

Por ejemplo: ls -l | grep archivo, nos mostrará todas las líneas del ls -l que concuerden con archivo.

Algunas opciones de grep son:

Vamos a hacer un ejemplo de una agenda sencilla, utilizando el comando grep y unos scripts de shell. En primer lugar necesitamos tener un archivo con unas cuantas líneas de la forma: "nombre: teléfono". Por lo menos cuatro o cinco líneas, como para probar este ejemplo.

Una vez que hemos creado el archivo, crearemos el script, que se llamará 110, y deberá contener la siguiente línea: grep -i "$*" agenda. Y para buscar un teléfono dentro de nuestra agenda haremos: 110 nombre.

tail

El comando tail nos permite ver la cola de un archivo, es decir sus últimas líneas (últimas 10 por omisión). Esto, aunque a simple vista no parezca útil, resulta de gran utilidad para ver archivos grandes como, por ejemplo, logs (archivos donde se guardan mensajes de estado y/o de errores).

Para probar el comando vamos a utilizar los logs del sistema, que se suelen guardar en /var/log, en particular /var/log/messages es el archivo que contiene gran parte de los mensajes del sistema. Podemos hacer tail /var/log/messages y compararlo con la salida de cat /var/log/messages.

Además a tail podemos indicarle cuántas líneas queremos que nos muestre. Con la opción -20, por ejemplo, le diríamos que nos muestre 20 líneas y así con cualquier número que le pasemos. Tambien podemos decirle que nos muestre el contenido del archivo a partir de una determinada línea, por ejemplo tail +5 archivo nos mostrará el contenido del archivo desde la línea 5 en adelante.

Otro comando similar a tail es head. Su comportamiento es muy similar, pero en lugar de mostrar las últimas líneas de la entrada, muestra las primeras.

sort

Este comando nos permite obtener una salida ordenada, si hacemos ls | sort obtendremos la salida de ls con un orden alfabético.

Ahora probemos ls -i | sort, sort ordena la salida de ls alfabéticamente, eso quiere decir que los números no van a estar ordenados de menor a mayor sino en orden alfabético. Para ordenarlos numéricamente existe la opción -n, ls -i | sort -n producirá una salida ordenada de menor a mayor. Si quisiéramos, en cambio, que lo ordene de mayor a menor, debemos usar ls -i | sort -nr, es decir -r ordena en orden inverso.

También podemos ordenar por una determinada columna, para entender esto de una manera más clara veamos la salida de ls -l, estas líneas pueden ser ordenadas por tamaño, por nombre, por fecha, etc. Para eso tenemos que indicarle cuál columna tiene que ordenar y con qué criterio. Notar que sort cuenta las columnas empezando de 0.

Por ejemplo:

ls -l | sort +4nr ordena la salida de ls por el tamaño dejando los más chicos al final. En este caso, la n, que indica ordenamiento numérico es opcional, ya que sort decide automáticamente el ordenamiento.

ls -l | sort +4n +8 ordena la salida de ls primero por tamaño y luego por el nombre del archivo. En este caso, es necesario poner la n, que indica ordenamiento numérico.

También existe un opcion -u que nos permite eliminar las lineas iguales adyacentes de la salida de sort. Es decir que si nuestra salida produce dos líneas iguales una debajo de otra, veríamos solamente una línea.

tr

Este comando nos permite transliterar caracteres, es decir cambiar determinado caracter por otro. Si escribimos tr 'a-z' 'A-Z' < archivo, veremos que tr transforma todas las minúsculas en mayúsculas.

Los parámetros del ejemplo anterior son rangos (de la 'a' a la 'z' y de la 'A' a la 'Z'), pero no es necesario que lo sean. Lo que sí nos exige tr es que los parámetros tengan la misma cantidad de caracteres, o bien que el segundo sea un solo caracter. En este último caso reemplazará todos los caracteres del primer parámetro con el del segundo.

La opción -c indica que deben transliterarse todos los caracteres que no estén incluídos en el primer parámetro.

Ejemplo difícil:

cat archivo | tr -c 'a-zA-Z' '\n' | tr 'A-Z' 'a-z' | sort -u

El primer tr convierte todo lo que no sea letras en \n (retorno de carro), el segundo convierte todas las mayúsculas en minúsculas y el sort del final las ordena alfabéticamente eliminando las líneas iguales, con lo que obtenemos una palabra por línea.

comm

Este comando nos sirve para comparar el contenido de dos archivos, línea por línea. Para poder probar este comando, debemos crear dos archivos parecidos, que tengan unas cuantas líneas en común, y otras distintas. Luego, debemos hacer: comm archivo1 archivo2.

La salida está separada en tres columnas: en la primera columna estarán las líneas que están en el primer archivo y no en el segundo, en la segunda columna veremos las líneas del segundo archivo que no estén en el primero y por último, en la tercera columna, las que están en los dos.

Además podemos indicar cuál de esas columnas no queremos que muestre, por ejemplo comm -12 arch1 arch2 muestra solamente la tercera columna, es decir, las líneas que están en ambos archivos.

El problema que tiene comm es que espera que las líneas estén ordenadas alfabéticamente, o en la misma posición dentro del archivo. De modo que puede suceder que archivos muy similares sean procesados por comm como archivos muy diferentes. Para procesamiento más avanzado de diferencias de archivos puede utilizarse el comando diff.

Ejemplo:

En /usr/share/dict/ normalmente tenemos un archivo diccionario, en el cual encontramos una palabra por renglón. En especial, el archivo words suele ser un symlink al diccinario del idioma de nuestro sistema.

Lo que vamos a hacer es armar un pequeño analizador ortográfico, usando los filtros recién vistos. Utilizaremos comm para verificar si la palabra está en el diccionario, y que nos avise si no está. Primero deberemos llevar el texto a una palabra por línea ordenada alfabéticamente (que es el ejemplo que utilizamos con tr). Y luego, utilizar comm para comparar con el diccionario.

El comando completo será:

cat archivo | tr -c 'a-zA-Z' '\n' | tr 'A-Z' 'a-z' | sort -u |
comm -23 - /usr/share/dict/words

Notar que el - como parámetro del comm le indica que use la entrada estándar para leer el primer archivo.


next up previous
Next: Filtros - Avanzados Up: Curso de GNU/Linux para Previous: Scripts de Shell -
hecho por Margarita Manterola y Maximiliano Curia