Uso de Grep y expresiones regulares para buscar patrones de texto en Linux

Introducción

El comando grep es uno de los comandos más útiles en un entorno de terminal Linux. El nombre grep significa “impresión global de expresiones regulares”. Esto significa que puedes usar grep para verificar si la entrada que recibe coincide con un patrón especificado. Este programa aparentemente trivial es extremadamente poderoso; su capacidad para ordenar la entrada basándose en reglas complejas lo convierte en un eslabón popular en muchas cadenas de comandos.

En este tutorial, explorarás las opciones del comando grep, y luego te sumergirás en el uso de expresiones regulares para realizar búsquedas más avanzadas.

Prerrequisitos

Para seguir esta guía, necesitarás acceso a una computadora que ejecute un sistema operativo basado en Linux. Esto puede ser un servidor privado virtual al que te hayas conectado con SSH o tu máquina local. Ten en cuenta que este tutorial fue validado usando un servidor Linux con Ubuntu 20.04, pero los ejemplos dados deberían funcionar en una computadora que ejecute cualquier versión de cualquier distribución de Linux.

Si planeas usar un servidor remoto para seguir esta guía, te recomendamos que primero completes nuestra guía de Configuración Inicial del Servidor. Hacerlo te configurará con un entorno de servidor seguro, incluyendo un usuario no root con privilegios sudo y un firewall configurado con UFW, que puedes usar para desarrollar tus habilidades en Linux.

Uso Básico

En este tutorial, usarás grep para buscar la Licencia Pública General de GNU versión 3 para varias palabras y frases.

Si estás en un sistema Ubuntu, puedes encontrar el archivo en la carpeta /usr/share/common-licenses. Cópialo a tu directorio de inicio:

  1. cp /usr/share/common-licenses/GPL-3 .

Si estás en otro sistema, usa el comando curl para descargar una copia:

  1. curl -o GPL-3 https://www.gnu.org/licenses/gpl-3.0.txt

También usarás el archivo de licencia BSD en este tutorial. En Linux, puedes copiarlo a tu directorio de inicio con el siguiente comando:

  1. cp /usr/share/common-licenses/BSD .

Si estás en otro sistema, crea el archivo con el siguiente comando:

  1. cat << 'EOF' > BSD
  2. Copyright (c) The Regents of the University of California.
  3. All rights reserved.
  4. Redistribution and use in source and binary forms, with or without
  5. modification, are permitted provided that the following conditions
  6. are met:
  7. 1. Redistributions of source code must retain the above copyright
  8. notice, this list of conditions and the following disclaimer.
  9. 2. Redistributions in binary form must reproduce the above copyright
  10. notice, this list of conditions and the following disclaimer in the
  11. documentation and/or other materials provided with the distribution.
  12. 3. Neither the name of the University nor the names of its contributors
  13. may be used to endorse or promote products derived from this software
  14. without specific prior written permission.
  15. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  16. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  19. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  21. OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  22. HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  23. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  24. OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  25. SUCH DAMAGE.
  26. EOF

Ahora que tienes los archivos, puedes comenzar a trabajar con grep.

En la forma más básica, usas grep para hacer coincidir patrones literales dentro de un archivo de texto. Esto significa que si pasas a grep una palabra para buscar, imprimirá cada línea en el archivo que contenga esa palabra.

Ejecuta el siguiente comando para usar grep y buscar cada línea que contenga la palabra GNU:

  1. grep "GNU" GPL-3

El primer argumento, GNU, es el patrón que estás buscando, mientras que el segundo argumento, GPL-3, es el archivo de entrada que deseas buscar.

La salida resultante será cada línea que contenga el texto del patrón:

Output
GNU GENERAL PUBLIC LICENSE The GNU General Public License is a free, copyleft license for the GNU General Public License is intended to guarantee your freedom to GNU General Public License for most of our software; it applies also to Developers that use the GNU GPL protect your rights with two steps: "This License" refers to version 3 of the GNU General Public License. 13. Use with the GNU Affero General Public License. under version 3 of the GNU Affero General Public License into a single ... ...

En algunos sistemas, el patrón que buscaste se resaltará en la salida.

Opciones Comunes

Por defecto, grep buscará el patrón especificado exacto dentro del archivo de entrada y devolverá las líneas que encuentre. Sin embargo, puedes hacer que este comportamiento sea más útil agregando algunas banderas opcionales a grep.

Si deseas que grep ignore el “caso” de tu parámetro de búsqueda y busque variaciones en mayúsculas y minúsculas, puedes especificar la opción -i o --ignore-case.

Busca cada instancia de la palabra license (con mayúsculas, minúsculas o mixtas) en el mismo archivo que antes con el siguiente comando:

  1. grep -i "license" GPL-3

Los resultados contienen: LICENSE, license y License:

Output
GNU GENERAL PUBLIC LICENSE of this license document, but changing it is not allowed. The GNU General Public License is a free, copyleft license for The licenses for most software and other practical works are designed the GNU General Public License is intended to guarantee your freedom to GNU General Public License for most of our software; it applies also to price. Our General Public Licenses are designed to make sure that you (1) assert copyright on the software, and (2) offer you this License "This License" refers to version 3 of the GNU General Public License. "The Program" refers to any copyrightable work licensed under this ... ...

Si hubiera una instancia con LiCeNsE, eso también se habría devuelto.

Si desea encontrar todas las líneas que no contienen un patrón especificado, puede utilizar la opción -v o --invert-match.

Busque cada línea que no contenga la palabra the en la licencia BSD con el siguiente comando:

  1. grep -v "the" BSD

Recibirá esta salida:

Output
All rights reserved. Redistribution and use in source and binary forms, with or without are met: may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ... ...

Dado que no especificó la opción “ignorar mayúsculas y minúsculas”, los dos últimos elementos se devolvieron como que no tienen la palabra the.

A menudo es útil conocer el número de línea en el que ocurren las coincidencias. Puede hacerlo utilizando la opción -n o --line-number. Vuelva a ejecutar el ejemplo anterior con esta bandera añadida:

  1. grep -vn "the" BSD

Esto devolverá el siguiente texto:

Output
2:All rights reserved. 3: 4:Redistribution and use in source and binary forms, with or without 6:are met: 13: may be used to endorse or promote products derived from this software 14: without specific prior written permission. 15: 16:THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 17:ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ... ...

Ahora puede hacer referencia al número de línea si desea hacer cambios en cada línea que no contenga the. Esto es especialmente útil al trabajar con código fuente.

Expresiones Regulares

En la introducción, aprendió que grep significa “impresión global de expresiones regulares”. Una “expresión regular” es una cadena de texto que describe un patrón de búsqueda particular.

Diferentes aplicaciones y lenguajes de programación implementan expresiones regulares ligeramente diferentes. En este tutorial solo explorará un pequeño subconjunto de la forma en que grep describe sus patrones.

Correspondencias literales

En los ejemplos anteriores en este tutorial, cuando buscabas las palabras GNU y the, en realidad estabas buscando expresiones regulares básicas que coincidieran con la cadena exacta de caracteres GNU y the. Los patrones que especifican exactamente los caracteres que se deben coincidir se llaman “literales” porque coinciden con el patrón literalmente, caracter por caracter.

Es útil pensar en estos como coincidentes con una cadena de caracteres en lugar de coincidir con una palabra. Esta distinción se volverá más importante a medida que aprendas patrones más complejos.

Todos los caracteres alfabéticos y numéricos (así como ciertos otros caracteres) se coinciden literalmente a menos que sean modificados por otros mecanismos de expresión.

Correspondencias de anclaje

Los anclajes son caracteres especiales que especifican dónde en la línea debe ocurrir una coincidencia para ser válida.

Por ejemplo, usando anclajes, puedes especificar que solo deseas conocer las líneas que coinciden con GNU al principio de la línea. Para hacer esto, podrías usar el ancla ^ antes de la cadena literal.

Ejecute el siguiente comando para buscar en el archivo GPL-3 y encontrar las líneas donde GNU ocurre al principio de una línea:

  1. grep "^GNU" GPL-3

Este comando devolverá las siguientes dos líneas:

Output
GNU General Public License for most of our software; it applies also to GNU General Public License, you may choose any version ever published

De manera similar, use el ancla $ al final de un patrón para indicar que la coincidencia solo será válida si ocurre al final de una línea.

Este comando coincidirá con cada línea que termine con la palabra and en el archivo GPL-3:

  1. grep "and$" GPL-3

Recibirá esta salida:

Output
that there is no warranty for this free software. For both users' and The precise terms and conditions for copying, distribution and License. Each licensee is addressed as "you". "Licensees" and receive it, in any medium, provided that you conspicuously and alternative is allowed only occasionally and noncommercially, and network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and provisionally, unless and until the copyright holder explicitly and receives a license from the original licensors, to run, modify and make, use, sell, offer for sale, import and otherwise run, modify and

Coindicando Cualquier Carácter

El carácter de punto (.) se usa en expresiones regulares para indicar que cualquier carácter único puede existir en la ubicación especificada.

Por ejemplo, para coincidir con cualquier cosa en el archivo GPL-3 que tenga dos caracteres y luego la cadena cept, usaría el siguiente patrón:

  1. grep "..cept" GPL-3

Este comando devuelve la siguiente salida:

Output
use, which is precisely where it is most unacceptable. Therefore, we infringement under applicable copyright law, except executing it on a tells the user that there is no warranty for the work (except to the License by making exceptions from one or more of its conditions. form of a separately written license, or stated as exceptions; You may not propagate or modify a covered work except as expressly 9. Acceptance Not Required for Having Copies. ... ...

Esta salida tiene instancias tanto de accept como de except y variaciones de las dos palabras. El patrón también habría coincidido con z2cept si se encontrara también.

Expresiones de Corchetes

Al colocar un grupo de caracteres dentro de corchetes (\[ y \]), puedes especificar que el carácter en esa posición puede ser cualquier carácter encontrado dentro del grupo de corchetes.

Por ejemplo, para encontrar las líneas que contienen too o two, especificarías esas variaciones de manera sucinta usando el siguiente patrón:

  1. grep "t[wo]o" GPL-3

La salida muestra que ambas variaciones existen en el archivo:

Output
your programs, too. freedoms that you received. You must make sure that they, too, receive Developers that use the GNU GPL protect your rights with two steps: a computer network, with no transfer of a copy, is not conveying. System Libraries, or general-purpose tools or generally available free Corresponding Source from a network server at no charge. ... ...

La notación de corchetes te ofrece algunas opciones interesantes. Puedes hacer que el patrón coincida con cualquier cosa excepto los caracteres dentro de un corchete comenzando la lista de caracteres dentro de los corchetes con un carácter ^.

Este ejemplo es como el patrón .ode, pero no coincidirá con el patrón code:

  1. grep "[^c]ode" GPL-3

Aquí está la salida que recibirás:

Output
1. Source Code. model, to give anyone who possesses the object code either (1) a the only significant mode of use of the product. notice like this when it starts in an interactive mode:

Observa que en la segunda línea devuelta, de hecho hay la palabra code. Esto no es un fallo de la expresión regular o grep. Más bien, esta línea fue devuelta porque anteriormente en la línea, se encontró el patrón mode, que se encuentra dentro de la palabra model. La línea fue devuelta porque hubo una instancia que coincidió con el patrón.

Otra característica útil de los corchetes es que puedes especificar un rango de caracteres en lugar de escribir cada carácter disponible individualmente.

Esto significa que si quieres encontrar cada línea que comienza con una letra mayúscula, puedes usar el siguiente patrón:

  1. grep "^[A-Z]" GPL-3

Aquí está la salida que devuelve esta expresión:

Output
GNU General Public License for most of our software; it applies also to States should not allow patents to restrict development and use of License. Each licensee is addressed as "you". "Licensees" and Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an System Libraries, or general-purpose tools or generally available free Source. User Product is transferred to the recipient in perpetuity or for a ... ...

Debido a algunos problemas de clasificación heredados, a menudo es más preciso utilizar clases de caracteres POSIX en lugar de rangos de caracteres como acabas de usar.

Discutir cada clase de caracteres POSIX estaría fuera del alcance de esta guía, pero un ejemplo que lograría el mismo procedimiento que el ejemplo anterior usa la clase de caracteres \[:upper:\] dentro de un selector de corchetes:

  1. grep "^[[:upper:]]" GPL-3

La salida será la misma que antes.

Repetir el Patrón Cero o Más Veces

Finalmente, uno de los metacaracteres más comúnmente usados es el asterisco, o *, que significa “repetir el carácter o expresión anterior cero o más veces”.

Para encontrar cada línea en el archivo GPL-3 que contenga un paréntesis de apertura y cierre, con solo letras y espacios simples entre ellos, use la siguiente expresión:

  1. grep "([A-Za-z ]*)" GPL-3

Obtendrás la siguiente salida:

Output
Copyright (C) 2007 Free Software Foundation, Inc. distribution (with or without modification), making available to the than the work as a whole, that (a) is included in the normal form of Component, and (b) serves only to enable use of the work with that (if any) on which the executable work runs, or a compiler used to (including a physical distribution medium), accompanied by the (including a physical distribution medium), accompanied by a place (gratis or for a charge), and offer equivalent access to the ... ...

Hasta ahora has usado puntos, asteriscos y otros caracteres en tus expresiones, pero a veces necesitas buscar esos caracteres específicamente.

Escapar Metacaracteres

Hay momentos en los que necesitarás buscar un punto literal o un corchete de apertura literal, especialmente al trabajar con código fuente o archivos de configuración. Debido a que estos caracteres tienen un significado especial en las expresiones regulares, debes “escapar” estos caracteres para indicarle a grep que no deseas utilizar su significado especial en este caso.

Escapas los caracteres utilizando el carácter de barra invertida (\) delante del carácter que normalmente tendría un significado especial.

Por ejemplo, para encontrar cualquier línea que comience con una letra mayúscula y termine con un punto, utiliza la siguiente expresión que escapa el punto final para que represente un punto literal en lugar del significado habitual de “cualquier carácter”:

  1. grep "^[A-Z].*\.$" GPL-3

Este es el resultado que verás:

Output
Source. License by making exceptions from one or more of its conditions. License would be to refrain entirely from conveying the Program. ALL NECESSARY SERVICING, REPAIR OR CORRECTION. SUCH DAMAGES. Also add information on how to contact you by electronic and paper mail.

Ahora veamos otras opciones de expresiones regulares.

Expresiones Regulares Extendidas

El comando grep admite un lenguaje de expresiones regulares más extenso utilizando la bandera -E o llamando al comando egrep en lugar de grep.

Estas opciones amplían las capacidades de las “expresiones regulares extendidas”. Las expresiones regulares extendidas incluyen todos los meta-caracteres básicos, junto con meta-caracteres adicionales para expresar coincidencias más complejas.

Agrupación

Una de las habilidades más útiles que abren las expresiones regulares extendidas es la capacidad de agrupar expresiones juntas para manipularlas o hacer referencia a ellas como una unidad.

Para agrupar expresiones juntas, colócalas entre paréntesis. Si deseas utilizar paréntesis sin usar expresiones regulares extendidas, puedes escaparlos con la barra invertida para habilitar esta funcionalidad. Esto significa que las siguientes tres expresiones son funcionalmente equivalentes:

  1. grep "\(grouping\)" file.txt
  2. grep -E "(grouping)" file.txt
  3. egrep "(grouping)" file.txt

Alternancia

Similar a cómo las expresiones entre corchetes pueden especificar diferentes opciones posibles para coincidencias de caracteres individuales, la alternancia te permite especificar coincidencias alternativas para cadenas o conjuntos de expresiones.

Para indicar alternancia, utiliza el carácter de tubería |. Estos se usan a menudo dentro de agrupaciones entre paréntesis para especificar que una de dos o más posibilidades debe considerarse una coincidencia.

Lo siguiente encontrará tanto GPL como General Public License en el texto:

  1. grep -E "(GPL|General Public License)" GPL-3

La salida se ve así:

Output
The GNU General Public License is a free, copyleft license for the GNU General Public License is intended to guarantee your freedom to GNU General Public License for most of our software; it applies also to price. Our General Public Licenses are designed to make sure that you Developers that use the GNU GPL protect your rights with two steps: For the developers' and authors' protection, the GPL clearly explains authors' sake, the GPL requires that modified versions be marked as have designed this version of the GPL to prohibit the practice for those ... ...

La alternancia puede seleccionar entre más de dos opciones agregando opciones adicionales dentro del grupo de selección separadas por caracteres de tubería adicionales (|).

Cuantificadores

Al igual que el meta-carácter * que coincide con el carácter o conjunto de caracteres anterior cero o más veces, existen otros meta-caracteres disponibles en las expresiones regulares extendidas que especifican el número de ocurrencias.

Para hacer coincidir un carácter cero o una vez, puedes usar el carácter ?. Esto hace que el carácter o conjunto de caracteres que aparecieron antes sean opcionales, en esencia.

Lo siguiente hace coincidir copyright y right al poner copy en un grupo opcional:

  1. grep -E "(copy)?right" GPL-3

Obtendrás este resultado:

Output
Copyright (C) 2007 Free Software Foundation, Inc. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License "Copyright" also means copyright-like laws that apply to other kinds of ...

El carácter + coincide con una expresión una o más veces. Esto es casi como el meta-carácter *, pero con el carácter +, la expresión debe coincidir al menos una vez.

La siguiente expresión coincide con la cadena free más uno o más caracteres que no son caracteres de espacio en blanco:

  1. grep -E "free[^[:space:]]+" GPL-3

Verás este resultado:

Output
The GNU General Public License is a free, copyleft license for to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to When we speak of free software, we are referring to freedom, not have the freedom to distribute copies of free software (and charge for you modify it: responsibilities to respect the freedom of others. freedomss that you received. You must make sure that they, too, receive protecting users' freedom to change the software. The systematic of the GPL, as needed to protect the freedom of users. patents cannot be used to render the program non-free.

Especificar la Repetición de Coincidencia

Para especificar el número de veces que se repite una coincidencia, use los caracteres de llave ({ y }). Estos caracteres le permiten especificar un número exacto, un rango, o un límite superior o inferior para la cantidad de veces que una expresión puede coincidir.

Utilice la siguiente expresión para encontrar todas las líneas en el archivo GPL-3 que contienen tripletes de vocales:

  1. grep -E "[AEIOUaeiou]{3}" GPL-3

Cada línea devuelta tiene una palabra con tres vocales:

Output
changed, so that their problems will not be attributed erroneously to authors of previous versions. receive it, in any medium, provided that you conspicuously and give under the previous paragraph, plus a right to possession of the covered work so as to satisfy simultaneously your obligations under this

Para coincidir con palabras que tienen entre 16 y 20 caracteres, use la siguiente expresión:

  1. grep -E "[[:alpha:]]{16,20}" GPL-3

Aquí está la salida de este comando:

Output
certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. c) Prohibiting misrepresentation of the origin of that material, or

Solo se muestran las líneas que contienen palabras de esa longitud.

Conclusión

grep es útil para encontrar patrones dentro de archivos o dentro de la jerarquía del sistema de archivos, por lo que vale la pena dedicar tiempo a familiarizarse con sus opciones y sintaxis.

Las expresiones regulares son aún más versátiles y se pueden usar con muchos programas populares. Por ejemplo, muchos editores de texto implementan expresiones regulares para buscar y reemplazar texto.

Además, la mayoría de los lenguajes de programación modernos utilizan expresiones regulares para realizar procedimientos en piezas específicas de datos. Una vez que entienda las expresiones regulares, podrá transferir ese conocimiento a muchas tareas comunes relacionadas con la informática, desde realizar búsquedas avanzadas en su editor de texto hasta validar la entrada de usuario.

Source:
https://www.digitalocean.com/community/tutorials/using-grep-regular-expressions-to-search-for-text-patterns-in-linux