Se sabe que el comando grep nos permite buscar, dentro de archivos, líneas que hagan match con un patrón, también, si no se especifica el nombre del archivo, este tomará la entrada estándar, con lo que se puede encadenar con otros filtros.
Por default, grep imprime las líneas encontradas en la salida estándar. Es decir, que podemos verlo directamente en la pantalla, o redireccionar la salida estándar a un archivo.
Obviamente el comando grep tiene muchas opciones, y aqui vamos a motrar solo algunas de ellas:
- -c En lugar de imprimir las líneas que coinciden, muestra el número de líneas que coinciden.
- -e PATRON nos permite especificar varios patrones de búsqueda o proteger aquellos patrones de búsqueda que comienzan con el signo -.
- -r busca recursivamente dentro de todos los subdirectorios del directorio actual.
- -v nos muestra las líneas que no coinciden con el patrón buscado.
- -i ignora la distinción entre mayúsculas y minúsculas.
- -n Numera las líneas en la salida.
- -E nos permite usar expresiones regulares. Equivalente a usar egrep.
- -o le indica a grep que nos muestre sólo la parte de la línea que coincide con el patrón.
- -f ARCHIVO extrae los patrones del archivo que especifiquemos. Los patrones del archivo deben ir uno por línea.
- -H nos imprime el nombre del archivo con cada coincidencia.
Aqui unos ejemplos prácticos:
Buscar todas las palabras que comiencen por a en un archivo:
dvarela@Latitude:~$ grep “a*” archivo
Buscar la palabra exacta –mydomain = – en el archivo main.cf
dvarela@Latitude:~$ grep -E “^mydomain = ” /etc/postfix/main.cf
La otra forma de buscar, sería:
dvarela@Latitude:~$ cat archivo | grep “a*”
Mostrar por pantalla, las líneas que contienen comentarios en el archivo /boot/grub/menu.lst:
dvarela@Latitude:~$ grep “#” /boot/grub/menu.lst
Enviar a un fichero las líneas del archivo /boot/grub/menu.lst que no son comentarios:
dvarela@Latitude:~$ grep -v “#” /boot/grub/menu.lst
Contar el número de interfaces de red que tenemos definidos en el fichero /etc/network/interfaces:
dvarela@Latitude:~$ grep -c “iface” /etc/network/interfaces
Mostrar las líneas de un fichero que contienen la palabra PEPE o NADOR:
dvarela@Latitude:~$ grep -e “PEPE” -e “NADOR” archivo
Otra alternativa es:
dvarela@Latitude:~$ grep “(PEPE|NADOR)” archivo
Mostrar las líneas de un archivo que contienen la palabra PEPE o NADOR, numerando las líneas de salida:
dvarela@Latitude:~$ grep -n -e “PEPE” -e “NADOR” archivo
Mostrar los ficheros que contienen la palabra SISTEMAS en el directorio actual y todos sus subdirectorios:
dvarela@Latitude:~$ grep -r “SISTEMAS” *
Ahora con expresiones regulares:
Obtener la dirección MAC de la interfaz de red eth0 de nuestra máquina:
dvarela@Latitude:~$ ifconfig eth0 | grep -oiE ‘([0-9A-F]{2}:){5}[0-9A-F]{2}’
Las opciones que he usado en grep son:
- -o Indica que la salida del comando debe contener sólo el texto que coincide con el patrón, en lugar de toda la línea, como es lo habitual.
- -i Lo he usado para que ignore la distinción entre mayúsculas y minúsculas.
- -E Indica que vamos a usar una expresión regular extendida.
En cuanto a la expresión regular, se divide en dos partes:
([0-9A-F]{2}:){5}: Buscamos 5 conjuntos de 2 carateres seguidos de dos puntos
[0-9A-F]{2} seguido por un conjunto de dos caracteres.
Como las direcciones MAC se representan en hexadecimal, los caracteres que buscamos son los números del 0 al 9 y las letras desde la A a la F.
Ahora vamos a extraer la lista de direcciones de correo electrónico de un archivo:
grep -Eio ‘[a-z0-9._-]+@[a-z0-9.-]+[a-z]{2,4}’ fichero.txt
Aqui se utiliza las mismas opciones que en el caso anterior:
- -o Indica que la salida del comando debe contener sólo el texto que coincide con el patrón, en lugar de toda la línea, como es lo habitual.
- -i Lo he usado para que ignore la distinción entre mayúsculas y minúsculas.
- -E Indica que vamos a usar una expresión regular extendida.
Ahora, analizando la expresión regular, tenemos que:
[a-z0-9._-]+@[a-z0-9.-]+[a-z]{2,4}
Al igual que la anterior la dividimos en partes:
[a-z0-9._-]+ Una combinación de letras, números, y/o los símbolos . _ y – de uno o más caracteres
@ seguido de una arroba
[a-z0-9.-]+ seguido de una cadena de letras, números y/o los símbolos . y –
[a-z]{2,4} seguido de una cadena de entre dos y cuatro caracteres.
Ahora vamos a obtener la dirección IP de la interfaz de red wlan0 de nuestra máquina:
dvarela@Latitude:~$ ifconfig wlan0 | grep -oiE ‘([0-9]{1,3}\.){3}[0-9]{1,3}’ | grep -v 255
En el ejemplo anterior, hemos tomado la información que nos ofrece ifconfig:
ifconfig wlan0
Hemos filtrado dicha información con el comando grep, obteniendo todas las direcciones IP que aparecen:
grep -oiE ‘([0-9]{1,3}\.){3}[0-9]{1,3}’
Y por último, hemos filtrado la salida del comando anterior, para eliminar la dirección de broadcast junto con la máscara de red para quedarnos sólo con la dirección IP de la máquina:
grep -v 255
Así que la línea anterior no mostraría las líneas que no contengan el valor 255, es decir, las direcciones de broadcast y máscara de red.
Analicemos ahora el comando grep:
grep -oiE ‘([0-9]{1,3}\.){3}[0-9]{1,3}’
Al igual que en los otros dos ejemplos de expresiones regulares uso las opciones -oiE en el comando grep:
- -o Indica que la salida del comando debe contener sólo el texto que coincide con el patrón, en lugar de toda la línea, como es lo habitual.
- -i Lo he usado para que ignore la distinción entre mayúsculas y minúsculas.
- -E Indica que vamos a usar una expresión regular extendida.
Y finalmente en cuanto a la expresión regular: ‘([0-9]{1,3}\.){3}[0-9]{1,3}’
([0-9]{1,3}\.){3}: Este representa 3 bloques de entre uno y tres dígitos separados por puntos. Observe que el punto es un metacaracter, se tiene que usar el caracter de escape \ para que no sea interpretado como un metacaracter, sino como un carácter normal.
[0-9]{1,3}: Representa el último bloque de la dirección IP, el cual está formado por un número de entre 1 y 3 dígitos.
Más ejemplos
grep como filtro: grep se utiliza muy a menudo como “filtro” con otros comandos. Esto le permite filtrar y eliminar la información inútil que se produce tras ejecutar un comando. Para usar grep como filtro, debe enviar el resultado del comando mediante grep por el canal de comunicación. El símbolo para el canal de comunicación es “|”.
El siguiente ejemplo muestra archivos que acaban por “.ps” creados en el mes de mayo:
dvarela@Latitude:~$ ls -l | grep May
grep cadenas de palabras múltiples: Para buscar un patrón que tenga más de una palabra, escriba la cadena entre comillas dobles o sencillas:
dvarela@Latitude:~$ grep “Louisa May” extensions
Louisa May Alcott x74236
dvarela@Latitude:~$
grep puede buscar una cadena de caracteres en un grupo de archivos. Cuando encuentre un patrón que cumple con las pautas en más de un archivo, imprime el nombre del archivo, seguido de una coma y de la línea que concuerda con el patrón:
dvarela@Latitude:~$ grep es *
actores:Charlton Heston
alaska:Alaska es el estado más extenso de los Estados Unidos.
wilde:libro. Los libros están bien o mal escritos.
dvarela@Latitude:~$
Cómo buscar líneas sin una cadena de caracteres determinada: Para buscar todas las líneas que no contengan una determinada cadena de caracteres, use la opción -v para grep. El siguiente ejemplo explica cómo buscar todas las líneas de los archivos del directorio personal medici que no contengan la letra e:
dvarela@Latitude:~$ ls
actores alaska interior tutores wilde
$ grep -v e *
actores:Lun Mar 14 10:00 PST 1936
wilde:Eso es todo.
dvarela@Latitude:~$
Más acerca de GREP
También puede usar el comando grep para buscar destinos definidos como patrón usando expresiones regulares. Las expresiones regulares están formadas por letras y números, así como por caracteres que tienen un significado especial para grep. Dichos caracteres especiales, llamados metacaracteres, también tienen un significado especial para el sistema y tienen que ir entre comillas o entre paréntesis precedidos por una barra inversa. Siempre que use una expresión regular de grep tras el indicador de comando, escríbala entre comillas, o precedida de metacaracteres de escape (como & ! . * $ ? y \) con una barra inversa (\).
- Un signo de intercalación (^) indica el inicio de línea. De modo que el comando:
dvarela@Latitude:~$ grep ‘^b’ list
busca cualquier línea del archivo list que empiece por “b.”
- Un signo de dólar ($) indica el fin de línea. El comando:
dvarela@Latitude:~$ grep ‘b$’ list
muestra cualquier línea en la que “b” sea su último carácter. Y el comando:
dvarela@Latitude:~$ $ grep ‘^b$’ list
muestra cualquier línea de list en la que “b” es el único carácter de la línea.
- En una expresión regular, el punto (.) busca cualquier carácter único. De forma que el comando
dvarela@Latitude:~$ grep ‘an.’ list
busca cualquier cadena de tres caracteres que contenga “an” como sus dos primeros, incluyendo “antes” “planta”, “finanzas” y “plan” (ya que los espacios también se tienen en cuenta).
- Cuando un asterisco (*) va detrás de un carácter, grep lo interpreta como “cero o más apariciones de dicho carácter”. Cuando el asterisco va detrás de una expresión regular, grep lo interpreta como “cero o más apariciones de caracteres que concuerden con el patrón.”
- Como incluye cero apariciones, el uso del asterisco no es nada intuitivo. Suponga que desea encontrar todas las letras que contengan una “qu”. Si escribe:
dvarela@Latitude:~$ grep ‘qu*’ list
funcionará según lo esperaba. Sin embargo, si quiere buscar todas las palabras que contengan la letra “n”, deberá escribir:
dvarela@Latitude:~$ grep ‘nn*’ list
Si quiere buscar todas las palabras que contengan el modelo “nn”, deberá introducir:
dvarela@Latitude:~$ grep ‘nnn*’ list
Puede intentar ver lo que ocurre al contrario.
- Para concordar cero o más apariciones de cualquier carácter de list, escriba:
dvarela@Latitude:~$ grep .* list
Cómo buscar metacaracteres
Supongamos que se desea buscar las líneas de un texto que tengan el símbolo ($). Si precede el signo de dólar de la expresión regular con una barra invertida (\), indicará a grep que ignore (escape) su significado especial. Esto es válido también para los demás metacaracteres (& ! . * ? y el propio \).
Por ejemplo, la expresión
dvarela@Latitude:~$ grep ^\.
Hace match o concuerda líneas que empiecen con un punto, y resulta especialmente útil cuando uno busca peticiones de formateo de nroff o troff (que empiecen con un punto).
La siguiente tabla, proporciona una lista de los patrones de búsqueda de modelos que más frecuentemente puede usar con grep..
Carácter | Concuerda |
---|---|
^ | El comienzo de una línea de texto |
$ | El final de una línea de texto |
. | Cualquier carácter único |
[…] | Cualquier carácter único de la lista o rango entre paréntesis |
[^…] | Cualquier carácter que no esté en la lista o el rango |
* | Cero o más apariciones del carácter precedente o de la expresión regular |
.* | Cero o más apariciones de cualquier carácter único |
\ | Ignora el significado especial del próximo carácter |
Observe que estos caracteres de búsqueda también se pueden usar en las búsquedas del editor de textos vi. Comillas dobles o sencillas en líneas de comando
Como se explicó anteriormente, las comillas se utilizan para delimitar el texto que desee que sea interpretado como una palabra. Por ejemplo, para que grep busque todos los archivos que contengan la frase “a la carga, mis valientes”, deberá introducir lo siguiente:
Comillas dobles o sencillas en líneas de comando
Como se explicó anteriormente, las comillas se utilizan para delimitar el texto que desee que sea interpretado como una palabra. Por ejemplo, para que grep busque todos los archivos que contengan la frase “a la carga, mis valientes”, deberá introducir lo siguiente:
dvarela@Latitude:~$ grep “a la carga, mis valientes” *
Las comillas simples (‘) también se pueden usar para agrupar frases con palabras múltiples formando unidades únicas, o para asegurarse de que determinados caracteres como por ejemplo $ sean interpretados literalmente (el metacarácter historia ! se interpreta siempre como tal, incluso si está entre comillas, salvo que lo haga preceder por una barra inversa). En cualquier caso, es una buena idea escribir caracteres como & ! $ ? . ; y \ precedidos de una barra inversa, si quiere que se interpreten como caracteres tipográficos normales.
Si escribe por ejemplo:
dvarela@Latitude:~$ grep $ list
verá todas las líneas de list. Sin embargo, si introduce:
dvarela@Latitude:~$ grep ‘\$’ list
sólo verá las líneas que contengan el caracter “$“..
Para mayor información acerca del comando grep(1), consulte man Pages(1).
Suerte!!