103.7 Lección 2
Certificación: |
LPIC-1 |
---|---|
Versión: |
5.0 |
Tema: |
103 Comandos GNU y Unix |
Objetivo: |
103.7 Buscar archivos de texto usando expresiones regulares |
Lección: |
2 de 2 |
Introducción
La transmisión de datos a través de una cadena de comandos canalizados permite la aplicación de filtros compuestos basados en expresiones regulares. Las expresiones regulares son una técnica importante que se utiliza no sólo en la administración de sistemas, sino también en la minería de datos y áreas relacionadas. Dos comandos son especialmente adecuados para manipular archivos y datos de texto usando expresiones regulares: grep
y sed
. grep
es un buscador de patrones y sed
es un editor de flujo. Son útiles por sí mismos, pero destacan todavía más cuando se usan en conjunción.
El buscador de patrones: grep
Uno de los usos más comunes de grep
es facilitar la inspección de archivos largos, utilizando la expresión regular como filtro aplicado a cada línea. Se puede usar para mostrar sólo las líneas que comienzan con un término determinado. Por ejemplo, grep
se puede usar para inspeccionar un archivo de configuración con módulos del kernel, mostrando sólo las líneas de opciones:
$ grep '^options' /etc/modprobe.d/alsa-base.conf options snd-pcsp index=-2 options snd-usb-audio index=-2 options bt87x index=-2 options cx88_alsa index=-2 options snd-atiixp-modem index=-2 options snd-intel8x0m index=-2 options snd-via82xx-modem index=-2
El carácter de barra vertical |
se puede emplear para redirigir la salida de un comando directamente a la entrada de grep
. El siguiente ejemplo usa una expresión entre corchetes para seleccionar líneas de la salida de fdisk -l
, comenzando con Disk /dev/sda
o Disk /dev/sdb
:
# fdisk -l | grep '^Disk /dev/sd[ab]' Disk /dev/sda: 320.1 GB, 320072933376 bytes, 625142448 sectors Disk /dev/sdb: 7998 MB, 7998537728 bytes, 15622144 sectors
La mera selección de líneas con coincidencias puede no ser apropiada para una tarea en particular, requiriendo ajustes en el comportamiento de grep
a través de sus opciones. Por ejemplo, la opción -c
o --count
le dice a grep
que muestre cuántas líneas tenían coincidencias:
# fdisk -l | grep '^Disk /dev/sd[ab]' -c 2
La opción se puede colocar antes o después de la expresión regular. Otras opciones importantes de grep son:
-c
o--count
-
En lugar de mostrar los resultados de la búsqueda, sólo muestra el recuento total de cuántas veces se produce una coincidencia en un archivo determinado.
-i
o--ignore-case
-
Hace que la búsqueda no distinga entre mayúsculas y minúsculas.
-f FILE
o--file=FILE
-
Indica un archivo que contenga la expresión regular a utilizar.
-n
o--line-number
-
Muestra el número de la línea.
-v
o--invert-match
-
Seleccioa todas las líneas, excepto las que contengan coincidencias.
-H
o--with-filename
-
Imprime también el nombre del archivo que contiene la línea.
-z
o--null-data
-
En lugar de que
grep
trate los flujos de datos de entrada y salida como líneas separadas (usando newline por defecto), toma la entrada o salida como una secuencia de líneas. Cuando se combina la salida del comandofind
usando su opción-print0
con el comandogrep
, la opción-z
o--null-data
debe usarse para procesar el flujo de la misma manera.
Aunque se activa de forma predeterminada cuando se proporcionan varias rutas de archivo como entrada, la opción -H
no está activada para archivos individuales. Eso puede ser crítico en situaciones especiales, como cuando grep
es llamado directamente por find
, por ejemplo:
$ find /usr/share/doc -type f -exec grep -i '3d modeling' "{}" \; | cut -c -100 artistic aspects of 3D modeling. Thus this might be the application you are This major approach of 3D modeling has not been supported oce is a C++ 3D modeling library. It can be used to develop CAD/CAM softwares, for instance [FreeCad
En este ejemplo, find
lista todos los archivos en /usr/share/doc
y luego pasa cada uno a grep
, que a su vez realiza una búsqueda que no distingue entre mayúsculas y minúsculas de 3d modeling
dentro del archivo. La tubería (pipe) está ahí sólo para limitar la longitud de salida a 100 columnas. Sin embargo, tenga en cuenta que no hay forma de saber de qué archivo provienen las líneas. Este problema se resuelve agregando -H
a grep
:
$ find /usr/share/doc -type f -exec grep -i -H '3d modeling' "{}" \; | cut -c -100 /usr/share/doc/openscad/README.md:artistic aspects of 3D modeling. Thus this might be the applicatio /usr/share/doc/opencsg/doc/publications.html:This major approach of 3D modeling has not been support
Ahora es posible identificar los archivos donde se encontró cada coincidencia. Para que la lista sea aún más informativa, se pueden agregar líneas iniciales y finales a las líneas con coincidencias:
$ find /usr/share/doc -type f -exec grep -i -H -1 '3d modeling' "{}" \; | cut -c -100 /usr/share/doc/openscad/README.md-application Blender), OpenSCAD focuses on the CAD aspects rather t /usr/share/doc/openscad/README.md:artistic aspects of 3D modeling. Thus this might be the applicatio /usr/share/doc/openscad/README.md-looking for when you are planning to create 3D models of machine p /usr/share/doc/opencsg/doc/publications.html-3D graphics library for Constructive Solid Geometry (CS /usr/share/doc/opencsg/doc/publications.html:This major approach of 3D modeling has not been support /usr/share/doc/opencsg/doc/publications.html-by real-time computer graphics until recently.
La opción -1
le indica a grep
que incluya una línea antes y una línea después cuando encuentre una línea con una coincidencia. Estas líneas adicionales se denominan líneas de contexto y se identifican en la salida con un signo menos después del nombre del archivo. Se puede obtener el mismo resultado con -C 1
o --context=1
y se pueden indicar otras cantidades de líneas de contexto.
Hay dos programas complementarios a grep: egrep
y fgrep
. El programa egrep
es equivalente al comando grep -E
, que incorpora características adicionales además de las expresiones regulares básicas. Por ejemplo, con egrep
es posible usar características extendidas de expresión regular, como ramificaciones:
$ find /usr/share/doc -type f -exec egrep -i -H -1 '3d (modeling|printing)' "{}" \; | cut -c -100 /usr/share/doc/openscad/README.md-application Blender), OpenSCAD focuses on the CAD aspects rather t /usr/share/doc/openscad/README.md:artistic aspects of 3D modeling. Thus this might be the applicatio /usr/share/doc/openscad/README.md-looking for when you are planning to create 3D models of machine p /usr/share/doc/openscad/RELEASE_NOTES.md-* Support for using 3D-Mouse / Joystick / Gamepad input dev /usr/share/doc/openscad/RELEASE_NOTES.md:* 3D Printing support: Purchase from a print service partne /usr/share/doc/openscad/RELEASE_NOTES.md-* New export file formats: SVG, 3MF, AMF /usr/share/doc/opencsg/doc/publications.html-3D graphics library for Constructive Solid Geometry (CS /usr/share/doc/opencsg/doc/publications.html:This major approach of 3D modeling has not been support /usr/share/doc/opencsg/doc/publications.html-by real-time computer graphics until recently.
En este ejemplo, 3D modeling
o 3D printing
coincidirán con la expresión, no distingue entre mayúsculas y minúsculas. Para mostrar sólo las partes de un flujo de texto que coinciden con la expresión utilizada por egrep
, use la opción -o
.
El programa fgrep
es equivalente a grep -F
, es decir, no analiza expresiones regulares. Es útil en búsquedas simples donde el objetivo es hacer coincidir una expresión literal. Por lo tanto, los caracteres especiales como el signo de dólar y el punto se tomarán literalmente y no por su significado en una expresión regular.
El editor de transmisiones: sed
El propósito del programa sed
es modificar datos basados en texto de una manera no interactiva. Significa que toda la edición se realiza mediante instrucciones predefinidas, no escribiendo arbitrariamente directamente en un texto que se muestra en la pantalla. En términos modernos, sed
puede entenderse como un analizador de plantillas: dado un texto como entrada, coloca contenido personalizado en posiciones predefinidas o cuando encuentra una coincidencia para una expresión regular.
Sed, como su nombre indica, es muy adecuado para texto transmitido a través de tuberías. Su sintaxis básica es sed -f SCRIPT
cuando las instrucciones de edición se almacenan en el archivo SCRIPT
o sed -e COMMANDS
para ejecutar COMMANDS
directamente desde la línea de comandos. Si no hay -f
ni -e
, sed
utiliza el primer parámetro que no es una opción como archivo de script. También es posible usar un archivo como entrada simplemente dando su ruta como argumento a sed
.
Las instrucciones sed
se componen de un solo carácter, posiblemente precedidas por una dirección o seguidas de una o más opciones, y se aplican a cada línea a la vez. Las direcciones pueden ser un número de una sola línea, una expresión regular o un rango de líneas. Por ejemplo, la primera línea de una secuencia de texto se puede eliminar con 1d
, donde 1
especifica la línea donde se aplicará el comando de eliminación d
. Para aclarar el uso de sed
, tome la salida del comando factor `seq 12`
, que devuelve los factores primos de los números del 1 al 12:
$ factor `seq 12` 1: 2: 2 3: 3 4: 2 2 5: 5 6: 2 3 7: 7 8: 2 2 2 9: 3 3 10: 2 5 11: 11 12: 2 2 3
La eliminación de la primera línea con sed
se logra mediante 1d
:
$ factor `seq 12` | sed 1d 2: 2 3: 3 4: 2 2 5: 5 6: 2 3 7: 7 8: 2 2 2 9: 3 3 10: 2 5 11: 11 12: 2 2 3
Se puede especificar un rango de líneas con una coma separadora:
$ factor `seq 12` | sed 1,7d 8: 2 2 2 9: 3 3 10: 2 5 11: 11 12: 2 2 3
Se puede utilizar más de una instrucción en la misma ejecución, separadas por punto y coma. En este caso, sin embargo, es importante encerrarlos entre paréntesis para que el punto y coma no sea interpretado por el shell:
$ factor `seq 12` | sed "1,7d;11d" 8: 2 2 2 9: 3 3 10: 2 5 12: 2 2 3
En este ejemplo, se ejecutaron dos instrucciones de eliminación, primero en las líneas que van del 1 al 7 y luego en la línea 11. Una dirección también puede ser una expresión regular, por lo que sólo las líneas con una coincidencia se verán afectadas por la instrucción:
$ factor `seq 12` | sed "1d;/:.*2.*/d" 3: 3 5: 5 7: 7 9: 3 3 11: 11
La expresión regular :.*2.*
coincide con cualquier aparición del número 2 en cualquier lugar después de dos puntos, lo que provoca la eliminación de las líneas correspondientes a los números con 2 como factor. Con sed
, cualquier cosa colocada entre barras (/
) se considera una expresión regular y, por defecto, se admiten todos los RE básicos. Por ejemplo, sed -e "/^#/d" /etc/services
muestra el contenido del archivo /etc/services
sin las líneas que comienzan con #
(líneas de comentarios).
La instrucción de eliminación d
es sólo una de las muchas instrucciones de edición proporcionadas por` sed`. En lugar de eliminar una línea, sed
puede reemplazarla con un texto dado:
$ factor `seq 12` | sed "1d;/:.*2.*/c REMOVED" REMOVED 3: 3 REMOVED 5: 5 REMOVED 7: 7 REMOVED 9: 3 3 REMOVED 11: 11 REMOVED
La instrucción c REMOVED
simplemente reemplaza una línea con el texto REMOVED
. En el caso del ejemplo, cada línea con una subcadena que coincida con la expresión regular :.*2.*
se ve afectada por la instrucción c REMOVED
. La instrucción a TEXT
copia el texto indicado por TEXT
en una nueva línea después de la línea con una coincidencia. La instrucción r FILE
hace lo mismo, pero copia el contenido del archivo indicado por FILE
. La instrucción w
hace lo contrario de r
, es decir, la línea se agregará al archivo indicado.
Con mucho, la instrucción sed
más utilizada es s/FIND/REPLACE/
, que se utiliza para reemplazar una coincidencia de la expresión regular FIND
con el texto indicado por REPLACE
. Por ejemplo, la instrucción s/hda/sda/
reemplaza una subcadena que coincide con el literal RE hda
con sda
. Sólo se reemplazará la primera coincidencia que se encuentre en la línea, a menos que la opción g
se coloque después de la instrucción, como en s/hda/sda/g
.
Un estudio de caso más realista ayudará a ilustrar las características de sed
. Suponga que una clínica médica desea enviar mensajes de texto a sus clientes, recordándoles sus citas programadas para el día siguiente. Un escenario de implementación típico se basa en un servicio de mensajería instantánea profesional, que proporciona una API para acceder al sistema responsable de entregar los mensajes. Estos mensajes generalmente se originan en el mismo sistema que ejecuta la aplicación que controla las citas del cliente, activados a una hora específica del día o algún otro evento. En esta situación hipotética, la aplicación podría generar un archivo llamado citas.csv
que contenga datos tabulados con todas las citas para el día siguiente, luego usado por sed
para procesar los mensajes de texto de un archivo de plantilla llamado template.txt
. Los archivos CSV son una forma estándar de exportar datos de consultas de bases de datos, por lo que las citas de muestra se pueden proporcionar de la siguiente manera:
$ cat appointments.csv "NAME","TIME","PHONE" "Carol","11am","55557777" "Dave","2pm","33334444"
La primera línea contiene las etiquetas de cada columna, que se utilizarán para hacer coincidir las etiquetas dentro del archivo de plantilla de muestra:
$ cat template.txt Hey <NAME>, don't forget your appointment tomorrow at <TIME>.
Los signos de menos de <
y de mayor que >
se colocaron alrededor de las etiquetas sólo para ayudar a identificarlas como etiquetas. El siguiente script de Bash analiza todas las citas en cola usando template.txt
como plantilla de mensaje:
#! /bin/bash TEMPLATE=`cat template.txt` TAGS=(`sed -ne '1s/^"//;1s/","/\n/g;1s/"$//p' appointments.csv`) mapfile -t -s 1 ROWS < appointments.csv for (( r = 0; r < ${#ROWS[*]}; r++ )) do MSG=$TEMPLATE VALS=(`sed -e 's/^"//;s/","/\n/g;s/"$//' <<<${ROWS[$r]}`) for (( c = 0; c < ${#TAGS[*]}; c++ )) do MSG=`sed -e "s/<${TAGS[$c]}>/${VALS[$c]}/g" <<<"$MSG"` done echo curl --data message=\"$MSG\" --data phone=\"${VALS[2]}\" https://mysmsprovider/api done
Un script de producción real también controlaría la autenticación, la verificación de errores y el registro, pero se trata de un ejemplo con funcionalidad básica para empezar. Las primeras instrucciones ejecutadas por sed
se aplican sólo a la primera línea — the address 1
in 1s/^"//;1s/","/\n/g;1s/"$//p
— para eliminar las comillas iniciales y finales — 1s/^"//
y 1s/"$//
— y reemplazar los separadores de campo con un carácter de nueva línea: 1s/","/\n/g
. Solo se necesita la primera línea para cargar los nombres de las columnas, por lo que las líneas que no coincidan se suprimirán con la opción -n
, lo que requiere que la marca p
se coloque después del último comando sed
para imprimir la línea coincidente. Luego, las etiquetas se almacenan en la variable TAGS
como una matriz Bash. Otra variable de tipo matriz Bash es creada por el comando mapfile
para almacenar las líneas que contienen las citas en la variable de matriz ROWS
.
Se emplea un bucle for
para procesar cada línea de cita que se encuentra en ROWS
. Luego, las comillas y los separadores en la cita - la cita está en la variable ${ROWS[$r]}
usada como una here string - se reemplazan por sed
, de manera similar a los comandos usados para cargar las etiquetas. Los valores separados para la cita se almacenan en la variable de matriz VALS
, donde los subíndices de matriz 0, 1 y 2 corresponden a los valores de NAME
, TIME
y PHONE
.
Finalmente, un bucle anidado for
recorre la matriz TAGS
y reemplaza cada etiqueta que se encuentra en la plantilla con su valor correspondiente en VALS
. La variable MSG
contiene una copia de la plantilla renderizada, actualizada por el comando de sustitución s/<${TAGS[$c]}>/${VALS[$c]}/g
en cada iteración de bucle a través de TAGS
.
Esto da como resultado un mensaje como: "Hey Carol, don’t forget your appointment tomorrow at 11am."
El mensaje se puede enviar como un parámetro a través de una solicitud HTTP con curl
, como un mensaje de correo o cualquier otro método similar.
Combinando grep y sed
Los comandos grep
y sed
pueden usarse juntos cuando se requieren procedimientos de minería de texto más complejos. Como administrador del sistema, es posible que desee inspeccionar todos los intentos de inicio de sesión en un servidor, por ejemplo. El archivo /var/log/wtmp
registra todos los inicios y cierres de sesión, mientras que el archivo /var/log/btmp
registra los intentos fallidos de inicio de sesión. Están escritos en formato binario, que se pueden leer con los comandos last
y lastb
, respectivamente.
La salida de lastb
muestra no solo el nombre de usuario utilizado en el intento de inicio de sesión incorrecto, sino también su dirección IP:
# lastb -d -a -n 10 --time-format notime user ssh:notty (00:00) 81.161.63.251 nrostagn ssh:notty (00:00) vmd60532.contaboserver.net pi ssh:notty (00:00) 132.red-88-20-39.staticip.rima-tde.net pi ssh:notty (00:00) 132.red-88-20-39.staticip.rima-tde.net pi ssh:notty (00:00) 46.6.11.56 pi ssh:notty (00:00) 46.6.11.56 nps ssh:notty (00:00) vmd60532.contaboserver.net narmadan ssh:notty (00:00) vmd60532.contaboserver.net nominati ssh:notty (00:00) vmd60532.contaboserver.net nominati ssh:notty (00:00) vmd60532.contaboserver.net
La opción -d
traduce el número de IP al nombre de host correspondiente. El nombre de host puede proporcionar pistas sobre el ISP o el servicio de alojamiento utilizado para realizar estos intentos de inicio de sesión incorrectos. La opción -a
coloca el nombre de host en la última columna, lo que facilita el filtrado aún por aplicar. La opción --time-format notime
suprime la hora en que se produjo el intento de inicio de sesión. El comando lastb
puede tardar algún tiempo en completarse si hubo demasiados intentos de inicio de sesión incorrectos, por lo que la salida se limitó a diez entradas con la opción -n 10
.
No todas las direcciones IP remotas tienen un nombre de host asociado, por lo que el DNS inverso no se aplica a ellas y se pueden descartar. Aunque se podría escribir una expresión regular para que coincida con el formato esperado para un nombre de host al final de la línea, probablemente sea más sencillo escribir una expresión regular para que coincida con una letra del alfabeto o con un solo dígito al final de la línea. El siguiente ejemplo muestra cómo el comando grep
toma el listado en su entrada estándar y elimina las líneas sin nombre de host:
# lastb -d -a --time-format notime | grep -v '[0-9]$' | head -n 10 nvidia ssh:notty (00:00) vmd60532.contaboserver.net n_tonson ssh:notty (00:00) vmd60532.contaboserver.net nrostagn ssh:notty (00:00) vmd60532.contaboserver.net pi ssh:notty (00:00) 132.red-88-20-39.staticip.rima-tde.net pi ssh:notty (00:00) 132.red-88-20-39.staticip.rima-tde.net nps ssh:notty (00:00) vmd60532.contaboserver.net narmadan ssh:notty (00:00) vmd60532.contaboserver.net nominati ssh:notty (00:00) vmd60532.contaboserver.net nominati ssh:notty (00:00) vmd60532.contaboserver.net nominati ssh:notty (00:00) vmd60532.contaboserver.net
El comando grep
con la opción -v
, muestra solo las líneas que no coinciden con la expresión regular dada. Una expresión regular que coincida con cualquier línea que termine con un número (es decir, [0-9]$
) capturará solo las entradas sin un nombre de host. Por lo tanto, grep -v '[0-9]$'
mostrará solo las líneas que terminan con un nombre de host.
La salida se puede filtrar aún más, manteniendo solo el nombre de dominio y eliminando las otras partes de cada línea. El comando sed
puede hacerlo con un comando de sustitución para reemplazar toda la línea con una referencia al nombre de dominio en ella:
# lastb -d -a --time-format notime | grep -v '[0-9]$' | sed -e 's/.* \(.*\)$/\1/' | head -n 10 vmd60532.contaboserver.net vmd60532.contaboserver.net vmd60532.contaboserver.net 132.red-88-20-39.staticip.rima-tde.net 132.red-88-20-39.staticip.rima-tde.net vmd60532.contaboserver.net vmd60532.contaboserver.net vmd60532.contaboserver.net vmd60532.contaboserver.net vmd60532.contaboserver.net
El paréntesis de escape en .* \(.*\)$
indica a sed
que recuerde esa parte de la línea, es decir, la parte entre el último carácter de espacio y el final de la línea. En el ejemplo, se hace referencia a esta parte con \1
y se usa para reemplazar la línea completa.
Está claro que la mayoría de los hosts remotos intentan iniciar sesión más de una vez, por lo que el mismo nombre de dominio se repite. Para suprimir las entradas repetidas, primero se deben ordenar (con el comando sort
) y luego pasar al comando uniq
:
# lastb -d -a --time-format notime | grep -v '[0-9]$' | sed -e 's/.* \(.*\)$/\1/' | sort | uniq | head -n 10 116-25-254-113-on-nets.com 132.red-88-20-39.staticip.rima-tde.net 145-40-33-205.power-speed.at tor.laquadrature.net tor.momx.site ua-83-226-233-154.bbcust.telenor.se vmd38161.contaboserver.net vmd60532.contaboserver.net vmi488063.contaboserver.net vmi515749.contaboserver.net
Esto muestra cómo se pueden combinar diferentes comandos para producir el resultado deseado. La lista de nombres de host se puede utilizar para escribir reglas de bloqueo de firewall o para tomar otras medidas para hacer cumplir la seguridad del servidor.
Ejercicios Guiados
-
El comando
last
muestra una lista de los últimos usuarios que iniciaron sesión, incluidas sus direcciones IP de origen. ¿Cómo se usaría el comandoegrep
para filtrar la salidalast
, mostrando sólo las apariciones de una dirección IPv4, descartando cualquier información adicional en la línea correspondiente? -
¿Qué opción se le debe pasar a
grep
para filtrar correctamente la salida generada por el comandofind
ejecutado con la opción-print0
? -
El comando
uptime -s
muestra la última fecha en la que se encendió el sistema, como en2019-08-05 20:13:22
. ¿Cuál será el resultado del comandouptime -s | sed -e 's/(.*) (.*)/\1/'
? -
¿Qué opción se le debe pasar a
grep
para que cuente las líneas coincidentes en lugar de mostrarlas?
Ejercicios Exploratorios
-
La estructura básica de un archivo HTML comienza con los elementos
html
,head
ybody
, por ejemplo:<html> <head> <title>News Site</title> </head> <body> <h1>Headline</h1> <p>Information of interest.</p> </body> </html>
Describe cómo se pueden usar las direcciones en
sed
para mostrar sólo el elementobody
y su contenido. -
¿Qué expresión
sed
eliminará todas las etiquetas de un documento HTML, manteniendo sólo el texto renderizado? -
Los archivos con extensión
.ovpn
son muy populares para configurar clientes VPN ya que contienen no sólo la configuración, sino también el contenido de las claves y certificados para el cliente. Estas claves y certificados se encuentran originalmente en archivos separados, por lo que deben copiarse en el archivo.ovpn
. Dado el siguiente extracto de una plantilla.ovpn
:client dev tun remote 192.168.1.155 1194 <ca> ca.crt </ca> <cert> client.crt </cert> <key> client.key </key> <tls-auth> ta.key </tls-auth>
Suponiendo que los archivos
ca.crt
,client.crt
,client.key
yta.key
están en el directorio actual, ¿cómo modificaríased
la configuración de la plantilla para reemplazar cada nombre de archivo por su contenido?
Resumen
Esta lección cubre los dos comandos de Linux más importantes relacionados con las expresiones regulares: grep
y sed
. Los scripts y los comandos compuestos se basan en grep
y sed
para realizar una amplia gama de tareas de filtrado y análisis de texto. La lección pasa por los siguientes pasos:
-
¿Cómo usar
grep
y sus variaciones comoegrep
yfgrep
? -
¿Cómo usar
sed
y sus instrucciones internas para manipular texto? -
Ejemplos de aplicaciones de expresión regular que utilizan
grep
ysed
.
Respuestas a los ejercicios guiados
-
El comando
last
muestra una lista de los últimos usuarios que iniciaron sesión, incluidas sus direcciones IP de origen. ¿Cómo se usaría el comandoegrep
para filtrar la salidalast
, mostrando sólo las apariciones de una dirección IPv4, descartando cualquier información adicional en la línea correspondiente?last -i | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
-
¿Qué opción se le debe pasar a
grep
para filtrar correctamente la salida generada por el comandofind
ejecutado con la opción-print0
?La opción
-z
o--null-data
, como enfind . -print0 | grep -z expression
. -
El comando
uptime -s
muestra la última fecha en la que se encendió el sistema, como en2019-08-05 20:13:22
. ¿Cuál será el resultado del comandouptime -s | sed -e 's/(.*) (.*)/\1/'
?Ocurrirá un error. De forma predeterminada, los paréntesis deben escaparse para usar referencias anteriores en
sed
. -
¿Qué opción se le debe pasar a
grep
para que cuente las líneas coincidentes en lugar de mostrarlas?Opción
-c
.
Respuestas a ejercicios exploratorios
-
La estructura básica de un archivo HTML comienza con los elementos
html
,head
ybody
, por ejemplo:<html> <head> <title>News Site</title> </head> <body> <h1>Headline</h1> <p>Information of interest.</p> </body> </html>
Describe cómo se pueden usar las direcciones en
sed
para mostrar sólo el elementobody
y su contenido.Para mostrar sólo
body
, las direcciones deben ser/<body>/,/<\/body>/
, como ensed -n -e '/<body>/,/<\/body>/p'
. La opción-n
se le pasa ased
por lo que no imprime líneas por defecto, de ahí el comandop
al final de la expresiónsed
para imprimir líneas coincidentes. -
¿Qué expresión
sed
eliminará todas las etiquetas de un documento HTML, manteniendo sólo el texto renderizado?La expresión
sed
s/<[^>]*>//g
reemplazará cualquier contenido encerrado en<>
por una cadena vacía. -
Los archivos con extensión
.ovpn
son muy populares para configurar clientes VPN ya que contienen no sólo la configuración, sino también el contenido de las claves y certificados para el cliente. Estas claves y certificados se encuentran originalmente en archivos separados, por lo que deben copiarse en el archivo.ovpn
. Dado el siguiente extracto de una plantilla.ovpn
:client dev tun remote 192.168.1.155 1194 <ca> ca.crt </ca> <cert> client.crt </cert> <key> client.key </key> <tls-auth> ta.key </tls-auth>
Suponiendo que los archivos
ca.crt
,client.crt
,client.key
yta.key
están en el directorio actual, ¿cómo modificaríased
la configuración de la plantilla para reemplazar cada nombre de archivo por su contenido?El comando
sed -r -e 's/(^[^.]*)\.(crt|key)$/cat \1.\2/e' < client.template > client.ovpn
reemplaza cualquier línea que termine en
.crt
o.key
por el contenido de un archivo cuyo nombre es igual a la línea. La opción-r
indica ased
que use expresiones regulares extendidas, mientras quee
al final de la expresión indica ased
que reemplace las coincidencias con la salida del comandocat \1.\2
. Las referencias inversas\1
y\2
corresponden al nombre de archivo y la extensión encontrados en la coincidencia.