Cómo usar grep para buscar cadenas en archivos en el shell de Linux

El comando GREP: una descripción general
El comando grep, que significa impresión de expresión regular global, es uno de los comandos más versátiles en un entorno de terminal Linux. Grep es un programa extremadamente poderoso que permite al usuario seleccionar y clasificar la entrada de acuerdo con reglas complejas, lo que lo convierte en una parte muy popular de numerosas cadenas de comandos.
El comando grep se usa principalmente para buscar en un texto o archivo líneas que contengan una coincidencia con las palabras/cadenas especificadas. De forma predeterminada, grep muestra las líneas coincidentes y se puede usar para buscar líneas de texto que coincidan con una o más expresiones regulares, y solo genera las líneas coincidentes.
requisitos previos
El comando grep es parte de las utilidades base de cualquier distribución de Linux, por lo que viene preinstalado en cualquier distribución de Linux de forma predeterminada, como AlmaLinux, CentOS, Debian, Linux Mint, Ubuntu, RHEL y RockyLinux.
La sintaxis básica del comando grep
La sintaxis básica del comando grep es la siguiente:
grep 'word' filename grep 'word' file1 file2 file3 grep 'string1 string2' filename cat otherfile | grep 'something' command | grep 'something' command option1 | grep 'data' grep --color 'data' fileName
Cómo usar el comando grep para buscar en un archivo
En el primer ejemplo, buscaré el usuario «tom» en el archivo passwd de Linux. Para buscar el archivo /etc/passwd para el usuario «tom», debe ingresar el siguiente comando:
grep tom /etc/passwd
A continuación se muestra la salida de muestra:
tom:x:1000:1000:tom,,,:/home/tom:/bin/bash
Tiene la opción de indicarle a grep que ignore las mayúsculas y minúsculas, es decir, haga coincidir abc, Abc, ABC y todas las combinaciones posibles con la opción -i como se muestra a continuación:
grep -i "tom" /etc/passwd
Uso recursivo de grep
Si tiene un montón de archivos de texto en una jerarquía de directorios, por ejemplo, los archivos de configuración de Apache en /etc/apache2/ y desea encontrar el archivo donde se define un texto específico, use la opción -r del comando grep para hacer una búsqueda recursiva. Esto realizará una operación de búsqueda recursiva a través de archivos para la cadena «197.167.2.9» (como se muestra a continuación) en el directorio /etc/apache2/ y todos sus subdirectorios:
grep -r "mydomain.com" /etc/apache2/
Alternativamente, se puede usar el siguiente comando:
grep -R "mydomain.com" /etc/apache2/
A continuación se muestran los resultados de muestra para una búsqueda similar en un servidor Nginx:
grep -r "mydomain.com" /etc/nginx/ /etc/nginx/sites-available/mydomain.com.vhost: if ($http_host != "www.mydomain.com") {
Aquí, verá el resultado de mydomain.com en una línea distinta precedida por el nombre del archivo (por ejemplo, /etc/nginx/sites-disponible/mydomain.com.vhost) en el que se encontró. La inclusión de los nombres de archivo en los datos de salida se puede suprimir fácilmente usando la opción -h (como se explica a continuación): grep -h -R «mydomain.com» /etc/nginx/. A continuación se muestra la salida de muestra:
grep -r "mydomain.com" /etc/nginx/ if ($http_host != "www.mydomain.com") {
Usando grep para buscar solo palabras
Cuando busque abc, grep coincidirá con todo tipo de cosas, a saber, kbcabc, abc123, aarfbc35 y muchas más combinaciones sin obedecer los límites de las palabras. Puede obligar al comando grep a seleccionar solo aquellas líneas que contienen coincidencias para formar palabras completas (aquellas que solo coinciden con la palabra abc), como se muestra a continuación:
grep -w "abc" file.txt
Ejemplo:
Usando grep para buscar dos palabras diferentes
Para buscar dos palabras diferentes, debe usar el comando egrep como se muestra a continuación:
egrep -w 'word1|word2' /path/to/file
Contar líneas para palabras coincidentes
El comando grep tiene la capacidad de informar la cantidad de veces que un patrón en particular ha coincidido para cada archivo usando la opción -c (recuento) (como se muestra a continuación):
grep -c 'word' /path/to/file
Además, los usuarios pueden usar la opción ‘-n’ antes de cada línea de salida con el número de línea en el archivo de texto del que se obtuvo (como se muestra a continuación):
grep -n 'root' /etc/passwd
A continuación se muestran las salidas de muestra:
1:root:x:0:0:root:/root:/bin/bash
Coincidencia inversa de Grep
Los usuarios pueden hacer uso de la opción -v para imprimir invierte la coincidencia, lo que significa que coincidiría solo con aquellas líneas que no contienen la palabra dada. Por ejemplo, imprima todas las líneas que no contengan la palabra par usando el siguiente comando:
grep -v par /path/to/file
Cómo enumerar solo los nombres de los archivos coincidentes
Debe usar la opción -l para enumerar los nombres de archivos cuyo contenido menciona una palabra en particular, por ejemplo, la palabra ‘primario’, usando el siguiente comando:
grep -l 'primary' *.c
Por último, tiene la opción de obligar a grep a mostrar la salida en colores específicos mediante el siguiente comando:
grep --color root /etc/passwd
A continuación se muestran resultados de muestra:
Anuncio publicitario
Cómo hacer que el comando grep maneje múltiples patrones de búsqueda
Puede haber situaciones en las que desee buscar varios patrones en un archivo determinado (o conjunto de archivos). En tales escenarios, debe usar la opción de línea de comando ‘-e’ que proporciona grep.
Por ejemplo, suponga que desea buscar las palabras «cómo», «para» y «forjar» en todos los archivos de texto presentes en su directorio de trabajo actual, así es como puede hacerlo:
grep -e how -e to -e forge *.txt
Aquí está el comando en acción:
La opción de línea de comandos ‘-e’ también ayuda en escenarios en los que el patrón comienza con un guión (-). Por ejemplo, si desea buscar, diga «-cómo», el siguiente comando no será útil:
grep -how *.txt
Es cuando usa la opción de línea de comando -e, el comando entiende qué es exactamente lo que está tratando de buscar en este caso:
grep -e -how *.txt
Aquí están ambos comandos en acción:
Cómo limitar la salida de grep a un número particular de líneas
En caso de que desee limitar la salida de grep a un número particular de líneas, puede hacerlo usando la opción de línea de comando ‘-m’. Por ejemplo, suponga que desea buscar la palabra «cómo» en testfile1.txt que contiene las siguientes líneas:
Pero el requisito es que grep deje de buscar después de que se hayan encontrado 3 líneas que contengan el patrón buscado. Entonces, para hacer esto, puede ejecutar el siguiente comando:
grep "how" -m3 testfile1.txt
Aquí está el comando en acción:
Continuando, esto es lo que dice la página de manual del comando:
If the input is standard input from a regular file, and NUM matching lines are output, grep ensuresthat the standard input is positioned to just after the last matching line before exiting, regardless of the presence of trailing context lines. This enables a calling process to resume a search.
Entonces, por ejemplo, si tiene un script bash que tiene un bucle y desea obtener una coincidencia por iteración de bucle, entonces usar ‘grep -m1’ hará lo necesario.
Cómo hacer que grep obtenga patrones del archivo
Si lo desea, también puede hacer que el comando grep obtenga patrones de un archivo. La opción de línea de comandos -f de la herramienta le permite hacer esto.
Por ejemplo, suponga que desea buscar en todos los archivos .txt en el directorio actual las palabras «cómo» y «a», pero desea proporcionar estas cadenas de entrada a través de un archivo llamado, digamos, «entrada», así es como puede hacer esto:
grep -f input *.txt
Aquí está el comando en acción:
Cómo hacer que grep muestre solo aquellas líneas que coinciden completamente con el patrón de búsqueda
Hasta ahora, hemos visto que, por defecto, grep coincide y muestra líneas completas que contienen patrones de búsqueda. Pero si el requisito es hacer que grep solo muestre aquellas líneas que coincidan completamente con el patrón buscado, entonces esto se puede hacer usando la opción de línea de comando ‘-x’.
Por ejemplo, supongamos que el archivo testfile1.txt contiene las siguientes líneas:
Y el patrón que quieres buscar es «¿cómo estás?». Entonces, para asegurarse de que grep solo muestre líneas que coincidan completamente con este patrón, utilícelo de la siguiente manera:
grep -x "how are you?" *.txt
Aquí está el comando en acción:
Cómo forzar a grep a no mostrar nada en la salida
Puede haber situaciones en las que no necesite el comando grep para producir nada en la salida. En cambio, solo desea saber si se encontró o no una coincidencia según el estado de salida del comando. Esto se puede lograr usando la opción de línea de comandos -q.
Mientras que la opción -q silencia la salida, el estado de salida de la herramienta se puede confirmar con el ‘echo $?’ dominio. En el caso de grep, el comando sale con el estado ‘0’ cuando tiene éxito (lo que significa que se encontró una coincidencia), mientras que sale con el estado ‘1’ cuando no se encontró ninguna coincidencia.
La siguiente captura de pantalla muestra los escenarios exitosos y no exitosos:
Cómo hacer que grep muestre el nombre de los archivos que no contienen un patrón de búsqueda
De forma predeterminada, el comando grep muestra el nombre de los archivos que contienen el patrón de búsqueda (así como las líneas coincidentes). Esto es bastante lógico, ya que eso es lo que se esperaba de esta herramienta. Sin embargo, puede haber casos en los que el requisito sea obtener los nombres de los archivos que no contienen el patrón buscado.
Esto también es posible con grep: las opciones -L le permiten hacer esto. Entonces, por ejemplo, para encontrar todos esos archivos de texto en el directorio actual que no contienen la palabra «cómo», puede ejecutar el siguiente comando:
grep -L "how" *.txt
Aquí está el comando en acción:
Cómo suprimir los mensajes de error producidos por grep
Si lo desea, también puede obligar a grep a silenciar cualquier mensaje de error que muestre en la salida. Esto se puede hacer usando la opción de línea de comando -s. Por ejemplo, considere el siguiente escenario en el que grep genera un error/advertencia relacionado con el directorio que encuentra:
Entonces, en este tipo de escenario, la opción de línea de comando -s ayuda. Vea abajo.
Entonces puede ver que el error/advertencia se silenció.
Cómo hacer que grep busque directorios recursivamente
Como se desprende claramente del ejemplo utilizado en el punto anterior, el comando grep no realiza una búsqueda recursiva de forma predeterminada. Para asegurarse de que su búsqueda de grep sea recursiva, use la opción de línea de comando -d y pásele el valor ‘recurse’.
grep -d recurse "how" *
Nota 1: El mensaje de error/advertencia relacionado con el directorio que discutimos en el punto anterior también se puede silenciar usando la opción -d; todo lo que tiene que hacer es pasarle el valor ‘saltar’.
Nota 2: Use ‘–exclude-dir=[DIR]’ opción para excluir directorios que coincidan con el patrón DIR de búsquedas recursivas.
Cómo hacer que grep termine nombres de archivo con carácter NULL
Como ya hemos discutido, la opción de línea de comando -l de grep se usa cuando solo desea que la herramienta muestre los nombres de archivo en la salida. Por ejemplo:
Ahora, lo que debe saber aquí es que cada nombre en el resultado anterior está separado/terminado por un carácter de nueva línea. Así es como puedes verificar eso:
Redirija la salida a un archivo y luego imprima el contenido del archivo:
Entonces, la salida del comando cat confirma la presencia de un carácter de nueva línea entre los nombres de los archivos.
Pero como ya sabrá, el carácter de nueva línea también puede ser parte del nombre de un archivo. Entonces, cuando se trata de casos en los que los nombres de archivo contienen una nueva línea y también están separados/terminados por una nueva línea, se vuelve difícil trabajar en la salida grep (especialmente cuando se accede a la salida a través de un script).
Sería bueno si el carácter de separación/terminación no fuera una nueva línea. Bueno, le alegrará saber que grep proporciona una opción de línea de comandos -Z que asegura que los nombres de archivo estén seguidos por un carácter NULL y no por una nueva línea.
Entonces, en nuestro caso, el comando se convierte en:
grep -lZ "how" *.txt
Así es como confirmamos la presencia del carácter NULL:
La siguiente es una opción de línea de comandos relacionada que debe conocer:
-z, --null-data Treat the input as a set of lines, each terminated by a zero byte (the ASCII NUL character) insteadof a newline. Like the -Z or --null option, this option can be used with commands like sort -z to process arbitrary file names.
Cómo usar GREP para encontrar errores en los archivos de registro
Grep es la navaja suiza del administrador de Linux cuando se trata de depurar errores en los servicios. La mayoría de los servicios de Linux tienen archivos de registro, donde informan errores. Estos archivos de registro pueden ser enormes y grep es un comando versátil y rápido para buscar, por ejemplo, una dirección IP de un sistema de conexión, una cadena de error o la dirección de correo electrónico de un usuario de correo afectado en mail.log.
Ejemplos:
Busque conexiones relacionadas con una dirección de correo electrónico específica, aquí ‘[email protected]’ en el archivo mail.log de un servidor.
grep [email protected] /var/log/mail.log
Resultado:
Nov 17 09:33:22 mail dovecot: pop3-login: Login: user=<[email protected]>, method=PLAIN, rip=192.168.0.112, lip=78.46.229.46, mpid=17596, TLS, session=<3uoa5ffQovld3Uep> Nov 17 09:33:23 mail dovecot: pop3([email protected])<17596><3uoa5ffQovld3Uep>: Disconnected: Logged out top=0/0, retr=1/6647, del=1/1, size=6630 Nov 17 09:34:14 mail dovecot: pop3-login: Login: user=<[email protected]>, method=PLAIN, rip=192.168.0.112, lip=78.46.229.46, mpid=17673, TLS, session=<fIIx6PfQkuBd3Uep> Nov 17 09:34:14 mail dovecot: pop3([email protected])<17673><fIIx6PfQkuBd3Uep>: Disconnected: Logged out top=0/0, retr=0/0, del=0/0, size=0 Nov 17 09:35:40 mail dovecot: pop3-login: Login: user=<[email protected]>, method=PLAIN, rip=192.168.0.112, lip=78.46.229.46, mpid=17868, TLS, session=<bd5L7ffQPsld3Uep> Nov 17 09:35:40 mail dovecot: pop3([email protected])<17868><bd5L7ffQPsld3Uep>: Disconnected: Logged out top=0/0, retr=0/0, del=0/0, size=0 Nov 17 09:35:58 mail dovecot: pop3-login: Login: user=<[email protected]>, method=PLAIN, rip=192.168.0.112, lip=78.46.229.46, mpid=17964, TLS, session=<sbpn7vfQevpd3Uep> Nov 17 09:35:58 mail dovecot: pop3([email protected])<17964><sbpn7vfQevpd3Uep>: Disconnected: Logged out top=0/0, retr=0/0, del=0/0, size=0 Nov 17 09:36:16 mail postfix/smtpd[6932]: NOQUEUE: reject: RCPT from unknown[1.2.3.4]: 504 5.5.2 <1.2.3.4>: Helo command rejected: need fully-qualified hostname; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<1.2.3.4>
Para monitorear continuamente un archivo de registro en busca de conexiones para esta dirección de correo electrónico, combine los comandos tail y grep como este:
tail -f /var/log/mail.log | grep [email protected]
Para salir de la función de reloj, presione [strg] + teclas c.
Más ejemplos de comandos GREP
En nuestro segundo tutorial de comandos GREP, puede encontrar aún más ejemplos de cómo usar este comando de Linux.