Laboratorio de Herramientas Computacionales Filtros1 Se da el nombre de filtros a un grupo de comandos que leen un flujo de datos de entrada, realizan una transformación sobre ellos y los escriben a un flujo de salida. Los filtros que veremos en este curso son: find, grep (y sus variantes fgrep y egrep), tr, uniq y cut; aunque también se consideran como filtros los comandos sort, tail y wc, que ya hemos abordado en la sección de comandos básicos. Comando find El comando find explora una rama de directorios buscando archivos que cumplan determinados criterios. En general, las opciones más comúnes que utiliza el comando find son: Opción -name archivo -size N[cbkMG] Descripción Verdadero si el nombre del archivo es igual a archivo. Se pueden usar los metacaracteres del shell como comodines, donde “?” representa una sola letra y “*” representa toda una cadena de 0 o más caracteres. Verdadero si el archivo es de N unidades de largo. Las unidades son “c” para bytes, “b” para bloques (1b = 512 bytes; ésta es la opción por omisión si no se escribe el sufijo de unidad), “k” para kilobytes (1k = 1,024 bytes), “M” para megabytes (1M = 1,048,576 bytes) y “G” para gigabytes (1G = 1,073,741,824 bytes). -atime N Verdadero si el archivo fue accedido dentro de los últimos N días. -mtime N Verdadero si el archivo fue modificado dentro de los últimos N días. -ctime N Verdadero si el archivo fue cambiado dentro de los últimos N días. -exec [comando] Verdadero si la ejecución de comando devuelve 0. -ok [comando] Parecido a -exec, sólo que comando es escrito en la pantalla y se solicita la confirmación del usuario para ejecutarlo, a lo que se tendrá que responder “Y” o “N”. -print Siempre es verdadero, muestra en pantalla cada ruta en donde find está buscando. -ls Siempre es verdadero, imprime la misma información que al ejecutar el comando “ls –l”. -newer archivo Verdadero si los archivos fueron modificados más recientemente que el tiempo de modificación que tiene archivo. Una vez ubicados los archivos, find puede realizar diversas acciones sobre ellos (generalmente en combinación con tuberías) tales como: • Ver o editar los archivos encontrados. 1 La autora original de este documento es la M. en I. Rosalía Mora Juárez, las actualizaciones al mismo fueron hechas por el M. en C. Sergio Rogelio Tinoco Martínez. R. M. J. y S. R. T. M. FIE 2013 [1] Laboratorio de Herramientas Computacionales • Guardar sus nombres en otro archivo. • Eliminar o renombrar los archivos. • Cambiar sus permisos de acceso. • Clasificarlos por grupos. Ejemplos: 1. Buscar en el directorio /var los archivos terminados en .log, e imprimir sus nombres en la terminal. find /var -name *.log 2. Buscar todos los archivos cuyo tamaño sea menor a 200KB. find /tmp -size -20k Nota: En los argumentos numéricos la opción +N significa > N, la opción -N significa < N y, la opción N, significa exactamente igual a N. 1. Buscar los archivos no visitados hace más de 30 días. find /var/spool/mail -atime +30 2. Buscar y eliminar los archivos vacíos. find /var/tmp -empty -exec rm {} \; Nota: Todo los argumentos que el shell encuentre entre la opción –exec y el argumento “;” (que se debe escapar con una diagonal invertida “\” para que el mismo shell no lo interprete de manera incorrecta) se pasarán como argumentos al comando ejecutado (en este ejemplo rm). La cadena “{}” será substituída por el nombre de los archivos encontrados por find (uno a la vez), durante la ejecución del comando. Esto es, en el ejemplo anterior se ejecutará el comando rm sobre cada uno de los archivos vacíos que find encuentre en la jerarquía de directorios a partir de /var/tmp. 3. Buscar archivos en los cuales, en lugar del nombre del usuario propietario, aparece un número (el número de identificación del usuario, UID – User ID). Esta situación se da cuando la cuenta del usuario propietario ha sido eliminada, pero los archivos creados por dicho usuario no. find /home -nouser -ls Debido a la cantidad tan grande de opciones que puede recibir el comando find, se sugiere consultar las páginas del manual para obtener mayor información sobre él. R. M. J. y S. R. T. M. FIE 2013 [2] Laboratorio de Herramientas Computacionales Comando grep El comando grep1 se utiliza como filtro por su característica de búsqueda de cadenas de caracteres en uno o más archivos, y porque lista todas las líneas que las contienen. La sintaxis del comando es: grep [-vliwn] cadena ARCHIVO(s) donde: -v: Lista las líneas que no contienen la cadena de caracteres buscada. -l: Lista sólo el nombre del primer archivo que contiene la cadena de caracteres buscada. -i: Ignora la diferencia entre letras mayúsculas y minúsculas. -w: Se debe utilizar cuando la cadena de caracteres buscada sea una sola palabra y se desée encontrarla completa, no como parte de otra más larga que la incluya. -n: Muestra el número de la línea en la que se encuentra la cadena de caracteres buscada. -r: Buscar recursivamente dentro de todos los subdirectorios del directorio actual. cadena: Cadena de caracteres a buscar. ARCHIVO(s): Nombre o nombres de los archivos en los que se quiere buscar la cadena de caracteres especificada. Importante: Cuando se empleen filtros se debe tomar en cuenta que, si se busca alguna cadena que contenga caracteres comodín (“*” y “?”), apóstrofes ('), comillas ("), redirectores de flujo (>, < y/o >>) o diagonales invertidas (“\”); SIEMPRE se deberá anteponer una barra invertida “\”. Esto con la finalidad de indicarle al shell que se trata de un carácter en sí, ignorando la función que representa el carácter. Por ejemplo: grep \*\"\'\?\< libro En una expresión como la anterior, el resultado que obtenemos será la búsqueda de la cadena *"'?< en el archivo libro. Ejemplos: 1. Crear un archivo con los días de la semana, uno por línea, y llamarle días. Buscar la cadena martes. grep martes días 2. Mostrar las líneas del archivo días que contienen la cadena es. grep es días 1 Global Regular Expression and Print. R. M. J. y S. R. T. M. FIE 2013 [3] Laboratorio de Herramientas Computacionales 3. Listar sólo los subdirectorios del directorio /usr (tomar en cuenta que, en la información impresa por el comando ls –l, la línea que empieza con un carácter “d” indica un directorio). ls -l /usr | grep '^d' 4. Listar sólo los archivos del directorio raíz cuyos permisos indican que todos los usuarios en el sistema pueden leerlos y modificarlos. ls -l / | grep '.......rw' 5. Buscar la ocurrencia de todas las palabras que comiencen con “m” minúscula en el archivo días. grep 'm*' días También se pueden aprovechar las tuberías para realizar filtros, lo anterior es equivalente a: cat días | grep 'm*' Para investigar: 1. En este ejemplo grep busca los usuarios sin contraseña dentro del archivo passwd: a) Inicialmente busca los caracteres al principio de la línea que no sean “:”. b) Luego busca los caracteres “::” (busca en el segundo lugar, que es el de la contraseña y que, si está vacío, indica que el usuario no cuenta con contraseña asignada). grep '^[^:]*::' /etc/passwd 2. Buscar los usuarios que no pueden entrar al sistema, es decir, que tienen un asterisco (*) en el lugar de la contraseña. Se utiliza “\” para escapar o eliminar el significado especial del segundo asterisco (*), que es el carácter específico que se busca. grep '^[^:]*:\*:' /etc/passwd Importante: Ninguna expresión regular de grep empata con el caracter salto de línea (‘\n’); las expresiones se aplican individualmente a cada línea. R. M. J. y S. R. T. M. FIE 2013 [4] Laboratorio de Herramientas Computacionales Comandos fgrep y egrep Existen dos versiones de grep que optimizan la búsqueda en casos particulares, éstas son: • fgrep (fixed grep –grep fijo– o fast grep –grep rápido–): Es una versión de grep que sólo acepta cadenas de caracteres y no expresiones regulares (es decir, que no interpreta metacaracteres), pero sí permite buscar varias de estas cadenas simultáneamente. • egrep (extended grep –grep extendido–): Esta versión acepta expresiones regulares complejas (extendidas con los operadores +, ?, | y paréntesis). Los comandos fgrep y egrep pueden emplear la opción -f archivo, donde archivo es un archivo que contiene la expresión a buscar. Ejemplos: 1. Busca la cadena martes en el archivo días. fgrep martes días 2. Crear el archivo buscar.fgrep con las cadenas “tes” y “jue”, una por línea. Luego emplear el comando fgrep, indicándole que lea la expresión de búsqueda desde este archivo. La sintaxis es: fgrep -f buscar.fgrep días El comando grep soporta fgrep y egrep como opciones -F y -E, respectivamente. Esto es: • Escribir grep -E es similar a egrep. • grep -E acepta expresiones regulares extendidas, y es la versión moderna del comando en GNU. • fgrep es idéntico a grep -F. Para investigar: 1. ¿Qué resultado se obtiene si se ejecutan las líneas siguientes? grep -F -f buscar.fgrep días egrep "tes|jue" días grep -E "tes|jue" días R. M. J. y S. R. T. M. FIE 2013 [5] Laboratorio de Herramientas Computacionales 2. En este ejemplo se buscan cadenas que inician opcionalmente por un dígito y los caracteres ab, (una o más veces), hasta encontrar la cadena 1234. Todo esto se hace en el archivo libro. egrep "([0-9]?ab)+1234" libro Comandos cut y paste En Unix la información solía guardarse en archivos de texto ASCII organizados por campos verticales separados con un carácter diferenciador. Este diferenciador solía ser un tabulador o el carácter “:”. Una de las necesidades que se produce en estos casos, consiste en separar los campos de un archivo y unirlos en otro. Para ello se utilizan los comando cut (cortar) y paste (pegar). En general la sintaxis de cut es: cut [-ddelimitador] [-fcampos] archivo donde: -d: Indica el separador de campos a usar (por defecto es el tabulador). -f: Especifica los campos a visualizar (por número y separados por comas). archivo: Ruta donde se encuentra el archivo a cortar. Ejemplos: Para explicar los comandos cut y paste vamos a utilizar como ejemplo el archivo /etc/passwd, en donde se encuentran las contraseñas (passwords) de los usuarios dados de alta en el sistema. A continuación se muestra un extracto típico del archivo /etc/passwd: root:x:0:0:root:/root:/bin/bash maria:x:500:500:Maria Muriel Cordero:/home/maria:/bin/bash practica:x:501:501:Usuario de practicas para Ksh:/home/practica:/bin/ksh wizardi:x:502:502:Wizard para nethack:/home/wizard:/bin/bash Como se puede observar, el contenido de /etc/passwd se compone de 7 campos separados por “:”. Los campos son, respectivamente y en este orden: nombre de usuario (login), contraseña encriptada, número de identificación de usuario (UID), número de identificación de grupo (GID), campo geco, directorio de inicio (home) de usuario y shell que asignado al usuario. Si ahora queremos emparejar los usuarios con su respectivo login y el shell que usan, debemos cortar los campos 1 y 7. Esto se hace con cut: cut -f1,7 -d: /etc/passwd obteniendo el resultado siguiente: R. M. J. y S. R. T. M. FIE 2013 [6] Laboratorio de Herramientas Computacionales root:/bin/bash maria:/bin/bash practica:/bin/ksh wizard:/bin/bash Ahora supongamos que tenemos dos archivos, salida1 y salida2, y que queremos unir el contenido de ambos archivos. Para ello usamos el comando paste. $ cat salida1 primer archivo, primer archivo, primer archivo, primer archivo, primer archivo, línea línea línea línea línea 1 2 3 4 5 $ cat salida2 segundo archivo, segundo archivo, segundo archivo, segundo archivo, segundo archivo, línea línea línea línea línea $ paste salida1 primer archivo, primer archivo, primer archivo, primer archivo, primer archivo, salida2 línea 1 línea 2 línea 3 línea 4 línea 5 1 2 3 4 5 segundo segundo segundo segundo segundo archivo, archivo, archivo, archivo, archivo, línea línea línea línea línea 1 2 3 4 5 Nótese que el comando paste une los archivos salida1 y salida2 línea por línea, separando las líneas de cada archivo con el carácter delimitador (en este ejemplo el carácter por defecto, el tabulador). Los archivos orginales no se alteran. Para investigar: También es posible especificar intervalos de campos. Esto es: $ cut -f5-7 -d: /etc/passwd root:/root:/bin/bash Maria Curiel Cordero:/home/maria:/bin/bash Usuario de practicas para Ksh:/home/practica:/bin/ksh Wizard para nethack:/home/wizard:/bin/bash Comando tr El comando tr sustituye (transforma) los caracteres de la entrada, por los caracteres indicados. La sustitución se hace carácter a carácter. La sintaxis es: R. M. J. y S. R. T. M. FIE 2013 [7] Laboratorio de Herramientas Computacionales tr [-dcs] caracteres_a_sustituir [caracteres_sustitutos] donde: -d: Eliminar los caracteres caracteres_a_sustituir. -c: Sustituye todos los caracteres, menos los indicados (sustituye el complemento). -s: Sustituye los caracteres repetidos con uno sólo. Se dice que los comprime. Ejemplos: 1. Sustituir todos los caracteres (expresados por el rango a-z) por su correspondiente carácter en mayúsculas (rango A-Z). cat días | tr a-z A-Z 2. Eliminar todas las vocales del archivo días. cat días | tr -d aeiou 3. Convertir los caracteres de salto de línea seguidos, en uno sólo. Dicho de otra manera, elimina los renglones en blanco. cat días | tr -s "\n" 4. Transformar todos los caracteres, que no sean letras o números, en un carácter guión (o signo menos). cat nota | tr -c "[a-zA-Z0-9]" "-" 5. Transformar todos los caracteres, que no sean letras o números, en salto de línea; y comprimir los saltos de línea repetidos, en uno sólo; es decir, cada palabra quedará sola en un renglón. cat nota | tr -cs "[a-zA-Z0-9]" "\n" 6. Comprimir los espacios en blanco (“ ”) en la salida, para poder cortar campos con el comando cut. ls -l /usr | tr -s " " | cut -f3,4 –d" " Comando uniq El comando uniq es el encargado de eliminar las redundancias. Por ejemplo, excluye todos los renglones adyacentes duplicados menos uno; es decir, elimina renglones repetidos consecutivos. Por lo general uniq se utiliza con otros comandos en tuberías. La sintaxis del comando es: R. M. J. y S. R. T. M. FIE 2013 [8] Laboratorio de Herramientas Computacionales uniq [-cd] donde: -c: Escribe el número de ocurrencias al inicio del renglón. -d: Imprimir sólo líneas duplicadas. Ejemplos: 1. Obtener un listado de usuarios conectados al sistema en un momento dado. Para ello, se hará uso de los comandos who y cut. who | cut -f1 -d' ' root maria maria practica El resultado no es del todo perfecto. Falta eliminar la aparición doble de maria. Entonces usamos el comando uniq: who | cut -f1 -d' ' | uniq root maria practica Nótese que -d' ' (o –d" ") indica que el carácter delimitador es un espacio en blanco. Para investigar: El ejemplo siguiente muestra las 5 palabras más frecuentes en un conjunto de archivos de GNU/Linux: cat *.txt | tr -cs "[a-zA-Z0-9]" "\n" | sort | uniq -c | sort -n | tail –n 5 En este ejemplo cat lista todos los archivos de texto, tr comprime los renglones del listado (y deja cada palabra por sí sola en un renglón), sort los ordena, uniq cuenta las ocurrencias y elimina repetidos, sort (con la opción –n) ordena por cantidad de ocurrencias y, tail, muestra las 5 ocurrencias más frecuentes. R. M. J. y S. R. T. M. FIE 2013 [9]