Grep y sed desmitificados

Grep. Lo escuchas mucho. Ves a esos chicos de TI crípticos escribiendo el comando, los administradores del sistema lo mencionan de pasada, incluso lo ves en algunos scripts de shell. Parece una de esas cosas que simplemente existe, pero no está hecha para ti. Este artículo cambiará eso: explicaremos y echaremos un vistazo rápido a grep (y su amigo menos famoso sed) en esta nueva versión de OS X Desmitificada..


Introducción

Grep

Grep es una utilidad de línea de comandos para buscar y filtrar algún tipo de entrada de texto en función de los parámetros que usted alimenta.

Grep es una utilidad de línea de comandos para buscar y filtrar algún tipo de entrada de texto en función de los parámetros que lo alimenta. En otras palabras, se ejecuta en la Terminal (Aplicaciones → Utilidades → Terminal), y se usa exclusivamente escribiendo comandos. Hay, por supuesto, envoltorios de GUI que ayudan un poco, pero ninguno es tan poderoso o versátil como el uso de la línea de comandos, así que eso es en lo que nos centraremos..

Todo eso está bien, pero ¿qué hace en realidad? ¿Lo de arriba suena demasiado vago? Aquí hay un ejemplo. Digamos que tiene un bloque de texto en un archivo llamado jungle.txt con cinco líneas:

Un león duerme en la jungla Un león duerme esta noche Un tigre se despierta en el pantano El loro observa a Wimoweh, wimoweh, wimoweh, wimoweh

Para encontrar la línea que contiene la palabra tigre, usamos grep así:

grep tiger jungle.txt

El resultado que nos dan es:

"Un tigre se despierta en el pantano"

Ok, eso está claro, ¿verdad? Retrocedamos aunque.

Actualizando Grep

Resulta que Mac grep es más lento que GNU grep, así que primero hagamos una actualización. Para instalar un grep más rápido, ingrese lo siguiente en la Terminal y presione entrar:

brew instala https://raw.github.com/Homebrew/homebrew-dupes/master/grep.rb

Tenga en cuenta que necesita Homebrew instalado para poder hacer esto, y para saber cómo instalar Homebrew, vea mi artículo anterior.

Una amplia gama de geeklets a menudo se basará en grep para obtener datos de archivos de texto grandes o sitios web recopilados

¿Qué hemos logrado al realizar esta actualización? Bueno, muchas aplicaciones utilizan la herramienta grep nativa instalada para funcionar. Por ejemplo, una amplia gama de geeklets a menudo se basará en grep para obtener datos de archivos de texto grandes o sitios web recolectados. Así, todos tus geeklets que usan grep ahora serán varias veces más rápidos en sus partes verdes. Además, es posible que a veces necesite grep algún tipo de registro de errores (digamos que tiene un gran registro de errores de una aplicación y el servicio de soporte de la aplicación le indica que los pegue "grep port-1723"). Si el registro tiene millones de líneas de código, podría ahorrar mucho tiempo usando este grep mucho más rápido..

Una vez que Homebrew instale su nuevo grep, intente hacer lo siguiente si creó los archivos. Si no, sigue adelante y hazlos, luego ejecuta el comando para asegurarte de que todo funcione.

grep tiger jungle.txt

Sed

Sed es un stream editor Dicho sin rodeos, toma la entrada, la edita y genera el contenido editado. Ya sea que se esté editando en un archivo o se esté alimentando directamente desde el Terminal, es completamente irrelevante para el sed, tiene una función altamente avanzada y configurable, y la realiza de la mejor manera posible..

Sed toma algo de entrada de texto, un comando sobre cómo cambiarlo y produce resultados modificados

Entonces, ¿dónde se usa sed? Edición de contenidos de archivos y similares, por supuesto, pero da la casualidad de que funciona perfectamente de la mano con grep. Veamos algunos ejemplos pur puros primero, sin embargo. Escriba lo siguiente en la Terminal:

echo "hola"

y presiona enter. La terminal dice hola. Ahora escribe

echo "hola" | sed 's / Hell / Heaven /'

y presiona enter. Deberías ver "Heaveno". ¿Lo que acaba de suceder? Mira, sed trabaja tomando dos argumentos. El primero es el feed, la entrada y el segundo es una cadena (se puede ver que es una cadena porque está entre comillas) que le indica qué acciones realizar en el primer argumento. En nuestro caso eso es:

  • s (sustituto)
  • / (delimitador: en nuestro caso barra diagonal, consulte el siguiente párrafo para conocer las alternativas)
  • Infierno (patrón de expresión regular para buscar)
  • Cielo (cadena de reemplazo)

El segundo elemento de la lista menciona alternativas al delimitador de barra diagonal; a veces resultarán muy útiles debido a que, por ejemplo, deben escribir direcciones URL o rutas de archivos. Tomemos por ejemplo el url myfolder / mysubfolder / myfile. Si ponemos esto en sed para reemplazarlo con myotherfolder / myotherfile, El parámetro se vería así: s / myfolder / mysubfolder / myfile / myotherfolder / myotherfile / que es solo una gran bolsa de tonterías - sed no puede saber cuál de esos fragmentos es la expresión regular y cuál es la cadena de reemplazo. Por lo tanto, necesitaríamos escapar Los forwardslashes en nuestra ruta de archivo con barra diagonal inversa, por lo que cada barra hacia adelante en el camino se convertiría en \ /. Supongo que puedes ver el problema. El nuevo parámetro sed se parece a esto:

sed 's / myfolder \ / mysubfolder \ / myfile / myotherfolder \ / myotherfile /'

Este formato apenas legible se denomina "valla de estacas", y para evitarlo, sed admite diferentes delimitadores como guiones bajos (_), dos puntos (:) y pipe (|). Por ejemplo, si quisiéramos usar el carácter de canalización como delimitador, terminaríamos con lo siguiente:

's | myfolder / mysubfolder / myfile | myotherfolder / myotherfile |'

Mucho mejor no?

Una cosa más, sin embargo. Dijimos que sed toma dos argumentos, pero solo damos uno, justo después de sed mando. Esto es debido al carácter de la pipa después de nuestro eco mando. La tubería sirve como un medio para dirigir la salida del operando izquierdo hacia la entrada del operando derecho. En nuestro caso, el personaje de la pipa dijo sed programa "Toma como entrada lo que sea que recibas de lo que haya en el lado izquierdo de mí". sed no tiene idea de que se trata de eco, no necesita saberlo. Todo lo que sabe es que está tomando entrada de texto. Discutir la tubería en más detalle que esto está fuera del alcance de este artículo, pero siéntase libre de leer si está interesado.

La tubería sirve como un medio para dirigir la salida del operando izquierdo hacia la entrada del operando derecho.

Entonces, ¿cómo lo combinamos con grep? Es exactamente lo mismo. Tomando nuestro ejemplo anterior, ingresemos lo siguiente en la terminal.

grep tiger jungle.txt | sed 's / swamp / desert /'

y obtenemos la salida

"Un tigre se despierta en el desierto"

Ahora veamos un caso de uso del mundo real.


Aplicación en el mundo real

Para nuestra "disección" tomaremos el comando grep + sed de un geeklet del clima popular y lo explicaremos poco a poco. Continúa y descarga el geeklet de muestra. Una vez descargado, ábralo con un editor de texto de cualquier tipo. Notarás que no es más que un archivo XML. Si no tiene experiencia con XML, no se preocupe, Josh ya hizo un artículo asombroso sobre Geektool y sus detalles. No vamos a lidiar con el meollo de la cuestión de todo hoy. En su lugar, vamos a centrarnos en la parte entre la etiquetas:

 curl --silent "http://xml.weather.yahoo.com/forecastrss?w=28348727&u=c" | grep -E '(Condiciones actuales: | C// '-e' s /// '-e' s /<\/b>// '-e' s /
// '-e' s /// '-e' s /<\/description>// '

Este desorden críptico es un simple comando de Terminal, nada más. Incluso puedes pegarlo en la Terminal y obtendrás las condiciones climáticas para Makati City en Filipinas, que el autor original lo estableció. El geeklet le dice a Geektool que ejecute dicho comando y tome cualquier salida que obtenga ejecutándolo. Echémosle un vistazo, segmento de tubo por segmento de tubo, y expliquemos en detalle:

curl --silent "http://xml.weather.yahoo.com/forecastrss?w=28348727&u=c"

rizo Es una herramienta para transferir datos con una sintaxis de URL. Esto significa que puede ir a una URL y recuperar datos de ella.

Curl es una herramienta que se utiliza para transferir datos con una sintaxis de URL en la línea de comandos.

Si pega la URL citada en su navegador (o simplemente haga clic aquí), notará que obtiene un archivo XML de Yahoo! - tienen un servicio de condiciones climáticas en vivo al que puede acceder y recuperar datos fácilmente. Esto es exactamente lo mismo que obtienes cuando rizo eso; Sólo en lugar del navegador, la entrada se envía a la Terminal. los --silencio la bandera le dice a curl que se calme sobre el progreso, el estado y los errores, de modo que la única salida que obtengamos sea la salida que necesitamos (o nada, si falla).

grep -E '(Condiciones actuales: | C 

A continuación, el carácter de la tubería, que significa la salida de rizo Se envía a grep como entrada. Grep recibe este archivo XML descargado en formato de texto y realiza una búsqueda en él con el -mi bandera, que significa Expresión Regular Extendida. El valor que está buscando es la cadena Condiciones actuales: o do (el carácter de la tubería dentro de un ereg significa "o"). Para aclaraciones adicionales, si escribió lo siguiente en nuestro ejemplo anterior:

grep -E '(tiger | weh)' jungle.txt

obtendrías

Un tigre se despierta en el pantano Wimoweh, wimoweh, wimoweh, wimoweh

porque devuelve todas las líneas que contienen "tigre" o "weh".

Entonces si corremos estos dos primeros segmentos de tubería juntos así:

curl --silent "http://xml.weather.yahoo.com/forecastrss?w=28348727&u=c" | grep -E '(Condiciones actuales: | C 

obtenemos lo siguiente:

Condiciones actuales:
Haze, 23 C

Pero solo queremos obtener "Haze, 23 C". Aquí es donde sed entra. Simplemente reemplazamos lo que no queremos con una cadena vacía (nada) eliminándola de manera efectiva.

sed -e 's / Condiciones actuales: //' -e 's /
// '-e' s /// '-e' s /<\/b>// '-e' s /
// '-e' s /// '-e' s /<\/description>// '

los -mi bandera es la abreviatura de --expresión = y nos permite encadenar múltiples sed comandos Por lo tanto, primero reemplazamos la cadena "Condiciones actuales:" por nada, y luego reemplazamos
sin nada, etc. hasta llegar al posible final de la línea ().

Al final, todo lo que queda es "Haze, 23 C".

Debo mencionar que el geeklet que hemos usado como ejemplo podría haberse hecho mucho mejor, pero la gran complejidad del comando utilizado parecía ser una muy buena oportunidad para cubrir varios ejemplos a la vez. El autor podría, por ejemplo, simplemente buscar la línea que contiene "Condiciones actuales:" y la línea que sigue con la -Un 1 Combinación de bandera, sin confiar en el símbolo de temperatura (en este caso, confiamos en Celsius, pero ¿y si quisiéramos Fahrenheit? La del autor do la búsqueda grep fallaría). No obstante, el ejemplo sirvió a un propósito - y eso fue presentarte al maravilloso mundo de grep y sed.


Más recursos

Si bien la enseñanza de expresiones regulares avanzadas y una funcionalidad más profunda de grep, curl y sed está muy lejos del alcance de este artículo (y de este sitio web), siéntase libre de consultar los siguientes recursos si desea saber más.

  • Guía sed
  • Guía para principiantes de grep
  • Ejemplos prácticos de comandos de Unix Grep
  • Documentación Grep en IBM
  • Documentación de curl
  • Expresiones regulares

Conclusión

Ahora sabes lo básico de grep, sed e incluso rizo. Si bien este curso intensivo estuvo lejos de ser lo suficiente como para convertirte en un experto, esperamos que sea al menos lo suficiente como para que te interese probar tu propia recolección de datos y realizar consultas. Por lo menos, es algo de lo que hablar alrededor del enfriador de agua el lunes.

Espero que lo hayas disfrutado, y si estás listo para un desafío, intenta reescribir el Geeklet no solo para que sea un símbolo de temperatura agnóstico, sino también para averiguar la ubicación del usuario por sí mismo, sin tener que modificar manualmente el 'w 'parámetro en el Yahoo! URL.