En Linux, la mayoría de los comandos tienen salida en pantalla, es decir, que muestran en la consola el resultado de lo que estás hadiendo. Con grep, puedes filtrar esta salida, e incluso mostrar el contenido de archivos ignorando los comentarios.
Además de quitar los comentarios de un archivo, también puedes utilizar expresiones regulares y así filtrar la salida en consola de cualquier resultado, incluso en archivos de logs en los que se van rellenando en tiempo real.
Este truco te vale tanto para Linux nativo, como para cualquier sistema basado en él. Por ejemplo WSL, o cualquier fork que lo tenga como base.
Cómo ocultar los comentarios al mostrar un archivo con grep
Esto es realmente útil cuando por ejemplo estás trabajando con algunos archivos de configuración que suelen traer comentarios y estados por defecto, por ejemplo los de apache o php que son bastante largos.
De esta forma, tienes de un vistazo las líneas que te interesan, e incluso las puedes exportar a un archivo con el comando de salida como ya vimos en otro artículo.
Voy a enseñarte a ignorar comentarios con el comando grep en este ejemplo con la configuración de apache, y luego con la de php, ya que usan caracteres diferentes para marcar los comentarios.
En el caso de apache, y la mayoría de los archivos en linux, un comentario empieza con almohadilla o hashtag #.
Si intentas hacer cat sobre el archivo, o tailf, te mostrará una salida similar a esto:
[...] # # Do NOT add a slash at the end of the directory path. # #ServerRoot "/etc/apache2" # # The accept serialization lock file MUST BE STORED ON A LOCAL DISK. # #Mutex file:${APACHE_LOCK_DIR} default # # The directory where shm and other runtime files will be stored. # DefaultRuntimeDir ${APACHE_RUN_DIR} # # PidFile: The file in which the server should record its process # identification number when it starts. # This needs to be set in /etc/apache2/envvars # PidFile ${APACHE_PID_FILE} # # Timeout: The number of seconds before receives and sends time out. # Timeout 300 # # KeepAlive: Whether or not to allow persistent connections (more than # one request per connection). Set to "Off" to deactivate. # KeepAlive On [...]
Como ves, todos los comentarios empiezan por #, incluso las opciones predeterminadas. Para ver el contenido del archivo en la consola sin que aparezcan todas estas líneas ejecuta:
cat /etc/apache2/apache2.conf | grep ^[^#] o grep ^[^#] /etc/apache2/apache2.conf
En ambos casos muestra la misma salida ¿verdad?, todo el contenido, pero ahora son solo 20 o 30 líneas y sin comentarios ni contenido extra que no esté en producción.
El primero de los casos, usando el símbolo de barra vertical o pipeline |, se puede aplicar a cualquier comando.
En el segundo caso, usas grep para atacar un único archivo, con una expresión regular como búsqueda.
Por ejemplo para el archivo de php.ini sería así:
cat /etc/php/7.2/apache2/php.ini | grep ^[^\;] o grep ^[^\;] /etc/php/7.2/apache2/php.ini
Si te fijas, ya que en el php.ini todos los comentarios empiezan con punto y coma ; hay que poner el carácter de escape o contrabarra \ delante de este símbolo. Es lo mismo para cualquier símbolo que interprete las expresiones regulares como ?[]{}().; etc.
Cómo filtrar cualquier contenido con el comando grep
Ahora la parte buena de esto, es que si quieres filtrar cualquier cosa en cualquier archivo también puedes, y no solo poniendo el texto directamente.
Ya sabes que si haces:
grep vichaunter /ruta/al/archivo.log
Mostraría todas las líneas que contengan la palabra vichaunter, pero se pueden hacer búsquedas más complejas con expresiones regulares, como por ejemplo para hacer coincidir líneas que contengan un texto y sean de una determinada fecha, etc.
La única limitación es que la búsqueda se hace en cada línea, por lo que si tienes un texto en varias líneas y te gustaría que se mostrara todo el párrafo, si tiene saltos no puede ser. Se mostrará solo la línea que tiene el texto.
Además, tienes también el comando sed, que es muy útil para abarcar por ejemplo rangos de fechas. Imagina que quieres ver los accesos que ha habido en el log de apache, del 1 al 30 de noviembre:
sed -n '/1\/Nov\/2018/,/30\/Dec\/2018/ p' /var/log/apache2/access.log
Esto te volcará todas las líneas que estén dentro de este rango de fechas, y puedes jugar mucho más con ello, si se te ocurren más formas útiles deja un comentario.
Otro ejemplo, vamos a usar grep para encontrar una cadena de texto que esté dentro de otras dos cadenas:
cat /var/log/apache2/access.log | grep -o -P '(?<=Mozilla).*(?=AppleWebKit)'
Esto mostraría únicamente el contenido que haya en cada línea entre Mozilla, y AppleWebKit dentro del log de apache.
Si no se te ocurre para qué puede servir, puedes crear un script que cuente las líneas, y con comandos sencillos conocer el número de accesos de cada tipo para hacer una estadística sencilla (ojo, por ejemplo).
Tiene infinidad de aplicaciones, incluso para buscar referencias en bases de datos que tengas en un archivo .sql, etc.
¿Qué otros usos le darías tú al comando grep o sed? Comenta y comparte