Comments

May 2, 2025

Cómo usar el lenguaje AWK para manipular texto en Linux

Introducción

Las utilidades de Linux suelen seguir la filosofía de diseño de Unix. Se fomenta que las herramientas sean pequeñas, utilicen archivos de texto sin formato para la entrada y salida, y operen de forma modular. Gracias a este legado, disponemos de una gran funcionalidad de procesamiento de texto con herramientas como sed y awk.

awkEs un lenguaje de programación y procesador de texto que permite manipular datos textuales de forma muy útil. En esta guía, explorarás cómo usar la awkherramienta de línea de comandos y cómo procesar texto.

Sintaxis básica

El awkcomando está incluido de forma predeterminada en todos los sistemas Linux modernos, por lo que no es necesario instalarlo para comenzar a usarlo.

awkEs especialmente útil al gestionar archivos de texto con un formato predecible. Por ejemplo, es excelente para analizar y manipular datos tabulares. Opera línea por línea e itera por todo el archivo.

De forma predeterminada, se utilizan espacios en blanco (tabuladores, etc.) para separar los campos. Afortunadamente, muchos archivos de configuración de Linux utilizan este formato.

El formato básico de un awkcomando es:

awk '/search_pattern/ { action_to_take_on_matches; another_action; }' file_to_parse

Puede omitir la parte de búsqueda o la parte de acción de cualquier awkcomando. Por defecto, la acción que se realiza si no se especifica la parte “acción” es “imprimir”. Esto simplemente imprime todas las líneas que coinciden.

Si no se proporciona la parte de búsqueda, awkrealiza la acción que aparece en cada línea.

Si se proporcionan ambos, awkutiliza la parte de búsqueda para decidir si la línea actual refleja el patrón y luego realiza las acciones en función de las coincidencias.

En su forma más simple, puedes usar awklike catpara imprimir todas las líneas de un archivo de texto en la pantalla.

Crea un favorite_food.txtarchivo que enumere las comidas favoritas de un grupo de amigos:

echo "carrot sandy
wasabi luke
sandwich brian
salad ryan
spaghetti jessica" > favorite_food.txt

Ahora use el awkcomando para imprimir el archivo en la pantalla:

awk '{print}' favorite_food.txt

Verás el archivo impreso en la pantalla:

Outputcarrot sandy
wasabi luke
sandwich brian
salad ryan
spaghetti jessica

Esto no es muy útil. Probemos awklas funciones de filtrado de búsqueda buscando el texto “arena” en el archivo:

awk '/sand/' favorite_food.txt

Outputcarrot sandy
sandwich brian

Como puedes ver, awkahora solo imprime las líneas que tienen los caracteres “sand” en ellas.

Usando expresiones regulares, puedes seleccionar partes específicas del texto. Para mostrar solo la línea que empieza con las letras “sand”, usa la expresión regular ^sand:

awk '/^sand/' favorite_food.txt

Esta vez, solo se muestra una línea:

Outputsandwich brian

De igual forma, puede usar la sección de acción para especificar qué información desea imprimir. Por ejemplo, para imprimir solo la primera columna, use el siguiente comando:

awk '/^sand/ {print $1;}' favorite_food.txt

Outputsandwich

Puede referenciar cada columna (delimitada por espacios) mediante variables asociadas a su número de columna. Por ejemplo, la primera columna es $1, la segunda es $2, y puede referenciar toda la línea con $0.

Variables internas y formato expandido

El awkcomando utiliza algunas variables internas para asignar ciertas piezas de información mientras procesa un archivo.

Las variables internas que awkutiliza son:

  • NOMBRE DE ARCHIVO : Hace referencia al archivo de entrada actual.
  • FNR : Referencia el número del registro actual en relación con el archivo de entrada actual. Por ejemplo, si tiene dos archivos de entrada, esto le indicaría el número de registro de cada archivo en lugar del total.
  • FS : El separador de campo actual que se utiliza para identificar cada campo de un registro. Por defecto, se establece en espacios.
  • NF : El número de campos en el registro actual.
  • NR : El número del registro actual.
  • OFS : El separador de campo para los datos de salida. Por defecto, se establece en espacios.
  • ORS : El separador de registros para los datos de salida. Por defecto, es un carácter de nueva línea.
  • RS : El separador de registros utilizado para distinguir registros separados en el archivo de entrada. Por defecto, es un carácter de nueva línea.

Puede cambiar los valores de estas variables a voluntad para adaptarlas a las necesidades de sus archivos. Normalmente, esto se hace durante la fase de inicialización del procesamiento.

Esto nos lleva a otro concepto importante. La awksintaxis es un poco más compleja que la que has usado hasta ahora. También hay bloques opcionales BEGINque ENDpueden contener comandos para ejecutarse antes y después del procesamiento del archivo, respectivamente.

Esto hace que nuestra sintaxis expandida se vea más o menos así:

awk 'BEGIN { action; }
/search/ { action; }
END { action; }' input_file

Las palabras clave BEGINy ENDson conjuntos específicos de condiciones, al igual que los parámetros de búsqueda. Coinciden antes y después de procesar el documento.

Esto significa que puedes cambiar algunas de las variables internas de la BEGINsección. Por ejemplo, el /etc/passwdarchivo se delimita con dos puntos ( :) en lugar de espacios.

Para imprimir la primera columna de este archivo, ejecute el siguiente comando:

awk 'BEGIN { FS=":"; }
{ print $1; }' /etc/passwd

Outputroot
daemon
bin
sys
sync
games
man
. . .

Puede usar los bloques BEGINy ENDpara imprimir información sobre los campos que está imprimiendo. Use el siguiente comando para transformar los datos del archivo en una tabla, con tabulaciones bien espaciadas \t:

awk 'BEGIN { FS=":"; print "User\t\tUID\t\tGID\t\tHome\t\tShell\n--------------"; }
{print $1,"\t\t",$3,"\t\t",$4,"\t\t",$6,"\t\t",$7;}
END { print "---------\nFile Complete" }' /etc/passwd

Verás este resultado:

OutputUser		UID		GID		Home		Shell
--------------
root 		 0 		 0 		 /root 		 /bin/bash
daemon 		 1 		 1 		 /usr/sbin 		 /bin/sh
bin 		 2 		 2 		 /bin 		 /bin/sh
sys 		 3 		 3 		 /dev 		 /bin/sh
sync 		 4 		 65534 		 /bin 		 /bin/sync
. . .
---------
File Complete

Como puedes ver, puedes formatear las cosas bastante bien aprovechando algunas de awklas características de .

Cada sección expandida es opcional. De hecho, la sección de acción principal es opcional si se define otra sección. Por ejemplo, se pueden hacer cosas como esta:

awk 'BEGIN { print "We can use awk like the echo command"; }'

Y verás este resultado:

OutputWe can use awk like the echo command

Ahora veamos cómo buscar texto dentro de los campos de salida.

Búsqueda de campos y expresiones compuestas

En uno de los ejemplos anteriores, imprimiste la línea del favorite_food.txtarchivo que comenzaba con “sand”. Esto fue fácil porque buscabas el comienzo de toda la línea.

¿Qué sucedería si quisieras averiguar si un patrón de búsqueda coincide al principio de un campo ?

Cree una nueva versión del favorite_food.txtarchivo que agregue un número de artículo delante de la comida de cada persona:

echo "1 carrot sandy
2 wasabi luke
3 sandwich brian
4 salad ryan
5 spaghetti jessica" > favorite_food.txt

Si desea encontrar todos los alimentos de este archivo que comienzan con “sa”, puede comenzar probando algo como esto:

awk '/sa/' favorite_food.txt

Esto muestra todas las líneas que contienen “sa”:

Output1 carrot sandy
2 wasabi luke
3 sandwich brian
4 salad ryan

Aquí, se busca cualquier instancia de “sa” en la palabra. Esto termina incluyendo palabras como “wasabi”, que tiene el patrón en el medio, o “sandy”, que no está en la columna deseada. En este caso, solo se buscan palabras que empiecen por “sa” en la segunda columna.

Puedes indicar awkque solo coincida con el comienzo de la segunda columna usando este comando:

awk '$2 ~ /^sa/' favorite_food.txt

Como puedes ver, esto nos permite buscar una coincidencia solo al comienzo de la segunda columna.

La field_num ~parte especifica que awksólo se debe prestar atención a la segunda columna.

Output3 sandwich brian
4 salad ryan

Puedes buscar fácilmente elementos que no coincidan incluyendo el carácter “!” antes de la tilde (~). Este comando devolverá todas las líneas que no tengan un alimento que empiece por “sa”:

awk '$2 !~ /^sa/' favorite_food.txt

Output1 carrot sandy
2 wasabi luke
5 spaghetti jessica

Si más adelante decide que solo le interesan las líneas que no comienzan con “sa” y el número de elemento es menor que 5, puede usar una expresión compuesta como esta:

awk '$2 !~ /^sa/ && $1 < 5' favorite_food.txt

Esto introduce algunos conceptos nuevos. El primero es la posibilidad de añadir requisitos adicionales para que la línea coincida mediante el &&operador. Con este operador, se puede combinar cualquier número de condiciones para que la línea coincida. En este caso, se utiliza este operador para añadir una comprobación de que el valor de la primera columna sea menor que 5.

Verás este resultado:

Output1 carrot sandy
2 wasabi luke

Puedes usarlo awkpara procesar archivos, pero también puedes trabajar con la salida de otros programas.

Procesamiento de la salida de otros programas

Puedes usar el awkcomando para analizar la salida de otros programas en lugar de especificar un nombre de archivo. Por ejemplo, puedes usar awkpara analizar la dirección IPv4 del ipcomando.

El ip acomando muestra la dirección IP, la dirección de difusión y otra información sobre todas las interfaces de red de su equipo. Para mostrar la información de la interfaz llamada eth0, utilice este comando:

ip a s eth0 

Verás los siguientes resultados:

Output2571: eth0@if2572: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:0b brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.11/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

Puedes usarlo awkpara apuntar a la inetlínea y luego imprimir solo la dirección IP:

ip a s eth0 | awk -F '[\/ ]+' '/inet / {print $3}'

La -Fbandera indica awkque se debe delimitar con barras o espacios usando la expresión regular [\/ ]+. Esto divide la línea inet 172.17.0.11/16en campos separados. La dirección IP se encuentra en el tercer campo porque los espacios al principio de la línea también cuentan como un campo, ya que se delimitó con espacios además de barras. Tenga en cuenta que, awken este caso, los espacios consecutivos se tratan como un solo espacio.

La salida muestra la dirección IP:

Output172.17.0.11

Encontrarás muchos lugares donde puedes usar awkpara buscar o analizar la salida de otros comandos.

Conclusión

A estas alturas, deberías tener una comprensión básica de cómo usar el awkcomando para manipular, formatear e imprimir selectivamente archivos y secuencias de texto. Sin embargo, Awk es un tema mucho más amplio y, en realidad, es un lenguaje de programación completo con asignación de variables, estructuras de control, funciones integradas y más. Puedes usarlo en tus propios scripts para formatear texto de forma fiable.

Para obtener más información sobre awk, puede leer el libro gratuito de dominio público de sus creadores que brinda muchos más detalles.

Stephen Dove
Comments

May 2, 2025

Dominando el comando sed en Linux: una guía completa

Introducción

El sedcomando “Editor de Streams” en Linux es una potente utilidad para la manipulación de texto. Permite a los usuarios realizar diversas operaciones, como buscar, reemplazar, insertar y eliminar texto en archivos. Este tutorial ofrece una guía completa para dominar el sedcomando con ejemplos prácticos, explicaciones de sintaxis y casos de uso avanzados.

¿Qué es el comando sed?

El sedcomando es un editor de flujo que procesa texto línea por línea. Esto permite modificar el contenido del archivo sin abrirlo directamente en un editor de texto. Se usa ampliamente en scripts de shell y administración de sistemas para automatizar las tareas de procesamiento de texto.

Características principales de sed

1. Coincidencia y reemplazo de patrones 2. Edición de archivos en el lugar 3. Filtrado y manipulación de texto 4. Compatibilidad con expresiones regulares 5. Operaciones multilínea

Sintaxis básica del sed comando

La sintaxis básica del sedcomando consta de tres componentes principales: las opciones del comando, un script que define las instrucciones de edición y el archivo que se va a procesar.

Esta estructura permite a los usuarios especificar el comportamiento del comando, definir las transformaciones de texto y aplicarlas al archivo deseado.

  1. Opciones de comando : Se utilizan para especificar el comportamiento del comando. Por ejemplo, esta -iopción se utiliza para la edición in situ de archivos, es decir, para sobrescribirlos.
  2. Script : El script define las instrucciones de edición. Puede estar entre comillas simples ( ') o dobles ( "). Puede contener uno o más comandos de edición, separados por punto y coma ( ;).
  3. Archivo de entrada : Este es el archivo que se procesará. Puede ser un solo archivo o una lista de archivos separados por espacios. Si no se especifica ningún archivo, sedse lee desde la entrada estándar.

La sintaxis básica del sedcomando es la siguiente:

sed [options] 'script' file

En esta sintaxis, sedes el comando, [options]son las opciones del comando, 'script'contiene los comandos de edición y filees el archivo que se va a procesar.

sed [options] 'script' file

Lo entenderás mejor con los ejemplos que aparecen a continuación.

sed 's/hello/world/' sample.txt

Esto reemplaza la primera aparición de “hola” con “mundo” en cada línea de sample.txt.

Opciones de uso común ensed

OpciónDescripciónEjemplo
-iEdición in sitused -i 's/old/new/' file.txt
-nSuprimir la impresión automáticased -n '/pattern/p' file.txt
-eEjecutar múltiples comandossed -e 's/old/new/' -e '/pattern/d' file.txt
-fLeer comandos de un archivosed -f script.sed file.txt
-rUtilice expresiones regulares extendidassed -r 's/old/new/' file.txt
-EUtilice expresiones regulares extendidas (similares a -r)sed -E 's/old/new/' file.txt
-zSeparar líneas con carácter NULsed -z 's/old/new/' file.txt
-lEspecifique la longitud de línea para el comando ‘l’sed -l 100 'l' file.txt
-bModo binario (no elimine los caracteres CR)sed -b 's/old/new/' file.txt

Casos de uso más comunes desed

A continuación se muestran algunos de los casos de uso más prácticos del sedcomando.

Primero, creemos un archivo de texto de muestra file1.txty escribamos en él el siguiente texto, para facilitar la comprensión y el seguimiento.

cat > file1.txt

Copie y pegue el siguiente texto:

Linux is a family of free and open-source operating systems based on the Linux kernel.
Operating systems based on Linux are known as Linux distributions or distros.
Examples include Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Buscar y reemplazar

En el siguiente comando, sse especifica la operación de sustitución y /son delimitadores. /Linux/Es el patrón de búsqueda y Unixes la cadena de reemplazo.

Nota: De forma predeterminada, el sedcomando solo reemplaza la primera aparición del patrón en cada línea y no reemplazará la segunda o tercera aparición en la línea.

sed 's/Linux/Unix/' file1.txt

Este comando reemplaza la primera aparición de “Linux” con “Unix” en cada línea.

Producción:

OutputUnix is a family of free and open-source operating systems based on the Linux kernel.
Operating systems based on Unix are known as Linux distributions or distros.
Examples include Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Unix, and many others.

Reemplazar globalmente en cada línea

La bandera de sustitución /g(reemplazo global) especifica el sedcomando para reemplazar todas las ocurrencias de la cadena en la línea.

sed 's/Linux/Unix/g' file1.txt

Este comando reemplaza todas las apariciones de “Linux” con “Unix” en cada línea.

Producción:

OutputUnix is a family of free and open-source operating systems based on the Unix kernel.
Operating systems based on Unix are known as Unix distributions or distros.
Examples include Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Unix, and many others.

Edición en el lugar

La opción `-i` permite la edición in situ del archivo. En pocas palabras, lo sobrescribe.

sed -i 's/Linux/Unix/' file1.txt

Este comando edita el archivo en su lugar, reemplazando “Linux” por “Unix” directamente en file1.txt. Sin -i, la inserción solo ocurre en la salida y no modifica el contenido del archivo. Para que el cambio sea persistente, debe usar la -iopción.

Eliminar líneas específicas

sed '2d' file1.txt

Este comando eliminará la segunda línea de file1.txt.

Producción:

OutputUnix is a family of free and open-source operating systems based on the Linux kernel.
Examples include Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Unix, and many others.

Suprime la -nimpresión automática del espacio de patrón y pes el comando de impresión.

sed -n '1,2p' file1.txt

Este comando imprime las líneas 1 a 2 de file1.txt.

Producción:

OutputUnix is a family of free and open-source operating systems based on the Unix kernel.
Operating systems based on Unix are known as Unix distributions or distros.

Eliminar líneas que coinciden con un patrón

Las /pattern/líneas coincidentes que contienen el patrón y la dbandera eliminan las líneas coincidentes.

sed '/kernel/d' file1.txt

Este comando eliminará todas las líneas que contengan la palabra “kernel”.

Producción:

OutputOperating systems based on Unix are known as Unix distributions or distros.
Examples include Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Unix, and many others.

Sustituir con un archivo de respaldo

El siguiente comando reemplazará todas las instancias de “Unix” por “Linux” y creará un archivo de respaldo con el file1.txt.baknombre del archivo anterior antes de reemplazarlo. Esto -i.bakpermite la edición in situ y crea un archivo de respaldo.

sed -i.bak 's/Unix/Linux/g' file1.txt

Producción:

OutputLinux is a family of free and open-source operating systems based on the Linux kernel.
Operating systems based on Linux are known as Linux distributions or distros.
Examples include Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Y aquí está el contenido del archivo de respaldo file1.txt.bak.

more file1.txt.bak
OutputUnix is a family of free and open-source operating systems based on the Unix kernel.
Operating systems based on Unix are known as Unix distributions or distros.
Examples include Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Unix, and many others.

Reemplazar tabulaciones con espacios

El siguiente comando reemplazará cada tabulación con cuatro espacios. La \tbandera coincide con las tabulaciones y /gsirve para el reemplazo global en toda la línea.

sed 's/\t/    /g' file1.txt

Producción:

Output   Linux is a family of free and open-source operating systems based on the Linux kernel.
Operating systems based on Linux are known as Linux distributions or distros.
Examples     include Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Eliminar líneas vacías

El siguiente comando eliminará todas las líneas vacías de file1.txt. El /^$comando “matches” elimina las líneas vacías y /dlas líneas coincidentes.

sed '/^$/d' file1.txt

Puede editar el file1.txtarchivo usando viel editor de texto y agregar algunas líneas vacías para probar este comando.

El siguiente comando imprime solo las líneas que contienen “Ubuntu”.

sed -n '/Ubuntu/p' file1.txt

La -nopción suprime la impresión automática. /Ubuntu/Coincide con las líneas que contienen el patrón y pse imprimen las líneas coincidentes.

Producción:

OutputExample includes Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Casos de uso avanzados desed

Esta sección consta de algunos casos de uso avanzados y más complicados del sedcomando.

Insertar texto antes de una línea

El siguiente comando inserta “Este es el texto insertado.” antes de la segunda línea en file1.txt.

sed -i '2i\This is inserted text.' file1.txt

La -iopción es para edición en el lugar y la 2i\bandera inserta texto antes de la segunda línea.

Nota: Sin -i, la inserción solo se produce en la salida y no modifica el contenido del archivo. Para que el cambio sea persistente, debe usar la -iopción con el sedcomando.

Producción:

OutputLinux is a family of free and open-source operating systems based on the Linux kernel.
This is inserted text.
Operating systems based on Linux are known as Linux distributions or distros.
Example includes Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Reemplazar la enésima ocurrencia de un patrón en una línea

Use los indicadores /1o /2para reemplazar la primera y la segunda aparición de un patrón en una línea. El siguiente comando reemplaza la segunda aparición de la palabra “Linux” por “Unix” en una línea.

sed 's/Linux/Unix/2' file1.txt

Producción:

OutputLinux is a family of free and open-source operating systems based on the Unix kernel.
This is inserted text.
Operating systems based on Linux are known as Unix distributions or distros.
Examples includes Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Añadir cadena después de una línea

El siguiente comando añade “Este es el texto añadido” después de la tercera línea file1.txt. Esta -iopción garantiza que los cambios se guarden y 3a\añade el texto después de la tercera línea especificada.

sed -i '3a\This is appended text.' file1.txt

Producción:

OutputLinux is a family of free and open-source operating systems based on the Linux kernel.
This is inserted text.
Operating systems based on Linux are known as Linux distributions or distros.
This is appended text.
Example includes Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Reemplazar una cadena al principio de una línea

La ^<pattern>bandera se usa para coincidir con un patrón específico al inicio de una línea. El siguiente comando reemplaza «Linux» por «Unix» solo si «Linux» aparece al inicio de una línea.

sed 's/^Linux/Unix/' file1.txt

Producción:

OutputUnix is a family of free and open-source operating systems based on the Linux kernel.
This is inserted text.
Operating systems based on Linux are known as Linux distributions or distros.
This is appended text.
Example includes Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Reemplazar cadena al final de una línea

El siguiente comando reemplaza “distros.” por “distributions” solo si aparece al final de una línea. La <pattern>$bandera se usa para hacer coincidir un patrón específico con el final de una línea.

sed 's/distros.$/distributions/' file1.txt

Producción:

OutputLinux is a family of free and open-source operating systems based on the Linux kernel.
This is inserted text.
Operating systems based on Linux are known as Linux distributions or distributions.
This is appended text.
Example includes Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Reemplazo sin distinción entre mayúsculas y minúsculas

El siguiente comando reemplaza “linux” por “Unix” sin distinguir entre mayúsculas y minúsculas. La Iopción hace que la coincidencia no distinga entre mayúsculas y minúsculas.

sed 's/linux/Unix/I' file1.txt

Extraer líneas entre patrones

El siguiente comando imprime todas las líneas entre “insertado” y “agregado”, inclusive.

sed -n '/inserted/,/appended/p' file1.txt
  1. ,:Operador de rango para hacer coincidir líneas entre dos patrones.
  2. p:Imprime líneas coincidentes.

Y la -nopción de suprimir la impresión automática de líneas.

Producción:

OutputThis is inserted text.
Operating systems based on Linux are known as Linux distributions or distros.
This is appended text.

Procesar varios archivos

El siguiente comando reemplaza “Linux” con “Unix” en ambos file1.txty file2.txtsobrescribe el archivo.

sed -i 's/Linux/Unix/' file1.txt file2.txt

Formato y numeración de líneas no vacías

El siguiente comando agrega números de línea a líneas no vacías en file1.txt.

sed '/./=' file1.txt | sed 'N;s/\n/ /'
  1. /./=: Coincide con líneas que no están vacías y las numera.
  2. N:Agrega la siguiente línea al espacio del patrón.
  3. s/\n/ /: Reemplaza el carácter de nueva línea con un espacio.

Producción:

Output1 Linux is a family of free and open-source operating systems based on the Linux kernel.
2 This is inserted text.
3 Operating systems based on Linux are known as Linux distributions or distros.
4 This is appended text.
5 Example includes Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Reemplazar cadena en un número de línea específico

Puede restringir el sedcomando para que reemplace la cadena en una línea específica. El siguiente comando reemplaza la cadena “distros” por “distributions” solo en la tercera línea.

sed '3 s/distros/distributions/' file1.txt

Producción:

Linux is a family of free and open-source operating systems based on the Linux kernel.
This is inserted text.
Operating systems based on Linux are known as Linux distributions or distributions.
This is appended text.
Example includes Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Reemplazo de cadena en un rango de líneas

También puede especificar un rango de números de línea para el sedcomando que reemplaza una cadena. El siguiente comando reemplaza solo las primeras apariciones de “Linux” por “Unix” entre las líneas 1 y 3.

sed '1,3 s/Linux/Unix/' file1.txt

Producción:

OutputUnix is a family of free and open-source operating systems based on the Linux kernel.
This is inserted text.
Operating systems based on Unix are known as Linux distributions or distros.
This is appended text.
Example includes Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Consideraciones de rendimiento para archivos grandes

Procesar archivos grandes sedpuede consumir muchos recursos, especialmente al trabajar con numerosas operaciones o conjuntos de datos muy grandes. Aquí tienes algunos consejos para optimizar el rendimiento y garantizar un uso eficiente del sedcomando:

1. Usar -npara minimizar la salida innecesaria : Esta -nopción suprime la impresión automática de cada línea y garantiza que solo se muestre la salida deseada. Esto reduce la sobrecarga al trabajar con archivos grandes.

Ejemplo:

sed -n '/pattern/p' largefile.txt

2. Simplifique los scripts : minimice el número de operaciones en un solo comando. Por ejemplo, en lugar de ejecutar varios sedcomandos secuencialmente, combínelos en un solo script para reducir la lectura de archivos.

Ejemplo:

sed -e 's/foo/bar/' -e '/pattern/d' largefile.txt

3. Entrada de flujo con tuberías : al procesar datos de otros comandos o flujos, utilice tuberías para evitar la creación de archivos intermedios y reducir la E/S de disco.

Ejemplo:

cat largefile.txt | sed 's/foo/bar/' > output.txt

4. Evite la edición in situ en archivos grandes : en lugar de modificar directamente archivos grandes, escriba la salida en un nuevo archivo y reemplace el original después de verificar la corrección.

Ejemplo:

sed 's/old/new/' largefile.txt > temp.txt && mv temp.txt largefile.txt

5. Alternativas de referencia : para archivos muy grandes, considere usar herramientas como awk, perl, o grep, que pueden ofrecer un mejor rendimiento para ciertas tareas.

Ejemplo:

awk '{gsub(/old/, "new"); print}' largefile.txt > output.txt

Puede consultar estos tutoriales sobre el comando AWK en Linux y Cómo usar el lenguaje AWK para manipular texto en Linux para obtener más información sobre el uso de awkcomandos en Linux.

Integración con scripts de Shell

El sedcomando se usa comúnmente en scripts de shell para automatizar tareas repetitivas de manipulación de texto. A continuación, un ejemplo:

#!/bin/bash
# Replace all occurrences of "foo" with "bar" in input.txt and save the result
sed 's/foo/bar/g' input.txt > output.txt

Este script procesa input.txty escribe la salida modificada en output.txt.

sedvs otras alternativas

Si bien sedes una herramienta eficaz y ligera para el procesamiento básico de texto, alternativas modernas como awky perlofrecen funciones adicionales, lo que las hace más adecuadas para tareas específicas. A continuación, se detallan las diferencias clave y cuándo usar cada una:

Cuándo utilizarlosed

  • Sustituciones o eliminaciones de texto rápidas y sencillas.
  • Transformaciones basadas en líneas en archivos.
  • Tareas que requieren una sobrecarga de scripting mínima.

Cuándo utilizarloawk

  • Manejo de datos estructurados como archivos CSV o TSV.
  • Realizar cálculos aritméticos junto con el procesamiento de texto.
  • Generar informes formateados a partir de datos de entrada.

Ejemplo:

awk -F, '{print $1, $3}' data.csv

Esto extrae e imprime el primer y tercer campo de un archivo CSV.

Cuándo utilizarloperl

  • Manipulaciones de texto complejas que involucran expresiones regulares avanzadas.
  • Combinando el procesamiento de texto con lógica o condiciones.
  • Cómo escribir scripts compactos pero potentes.

Ejemplo:

perl -pe 's/(error)/WARNING: $1/' logfile.txt

Esto agrega un prefijo “ADVERTENCIA:” a las líneas que contienen la palabra “error”.

Conclusión

Dominar el sedcomando mejora tu capacidad para manipular y procesar texto eficientemente en Linux. Sus potentes funciones y su integración fluida con scripts lo convierten en una herramienta valiosa para tareas de manipulación de texto.

Próximos pasos

Tras dominar los conceptos básicos de sed, podrá aprender técnicas y casos de uso más avanzados. Puede utilizar la siguiente serie de tutoriales sobre sedtemas relacionados que le ayudarán a profundizar su comprensión y mejorar sus habilidades de procesamiento de texto:

  • Conceptos básicos del uso del sededitor de secuencias para manipular texto en Linux
  • Intermedio sed: Manipulación de flujos de texto en un entorno Linux

Estos tutoriales abarcan diversos temas, desde sedoperaciones básicas hasta técnicas más complejas de manipulación de texto. Son un recurso valioso para quienes desean dominar el procesamiento de texto en la línea de comandos.

Preguntas frecuentes

¿Qué es sedun comando en Linux?

El sedcomando “Editor de Flujo” en Linux es una potente herramienta de procesamiento de texto que permite realizar transformaciones básicas de texto en un flujo de entrada (un archivo o la entrada de una canalización). Permite buscar, reemplazar, eliminar e insertar texto, lo que lo hace muy útil para automatizar tareas de manipulación de texto.

¿Cuando utilizarlo sed?

Puede utilizarlo seden los siguientes escenarios:

  • Reemplazo de texto : reemplace palabras, frases o patrones en archivos o transmisiones.
  • Eliminación de texto : elimina líneas o patrones específicos.
  • Edición en el lugar : modifique archivos directamente sin necesidad de abrir un editor de texto.
  • Procesamiento por lotes : realice la misma operación en varios archivos mediante scripts.
  • Inserción/extracción de texto : inserte o extraiga texto específico en archivos estructurados, como archivos de configuración o registros.

¿Cómo utilizarlo sedcorrectamente?

Para utilizarlo sedeficazmente, siga estos pasos:

sed [options] 'command' file
  • command:La sedoperación (por ejemplo, spara sustituir, dpara eliminar).
  • file:El archivo de destino a procesar.

Prueba antes de aplicar en el lugar: primero, ejecute el comando sin la -iopción ‘ para ver el resultado antes de modificar los archivos directamente.

Utilice expresiones regulares: aproveche el soporte de sed para expresiones regulares para hacer coincidir y manipular patrones complejos.

Encadenar varios comandos: utilice ;o -epara ejecutar varios sedcomandos en una sola operación.

¿Cómo usar sed para reemplazar texto?

Para reemplazar texto, utilice el scomando substituir con esta sintaxis:

sed 's/old_text/new_text/' file

Ejemplos:

  • Reemplace la primera aparición de “foo” con “bar” en cada línea:
sed 's/foo/bar/' file.txt
  • Reemplace todas las ocurrencias de “foo” con “bar” globalmente:
sed 's/foo/bar/g' file.txt
  • Reemplazo en el lugar (modifica el archivo directamente):
sed -i 's/foo/bar/g' file.txt

¿Cómo ejecuto un sedcomando?

Puede ejecutar un sedcomando directamente desde la terminal utilizando esta sintaxis básica:

sed 'command' filename

Ejemplo:

Para imprimir líneas que contengan la palabra “error” y reemplazar “error” por “advertencia” en un archivo llamado log.txt:

sed 's/error/warning/' log.txt

¿Cuál es la diferencia entre los comandos grepy seden Linux?

Característicagrepsed
ObjetivoBuscar patrones en uno o más archivosEditar secuencias de texto
ProducciónImprime líneas que contienen el patrón.Imprime el texto editado
ComportamientoBuscar, filtrarBuscar, Reemplazar, Insertar, Eliminar
Usogrep pattern filesed 'command' file
Buscar y reemplazarSí (limitado)
Edición en el lugarNo
Expresiones regulares
Operaciones multilíneaNo
Filtrado de textoNo
Casos de uso comunesBúsqueda de registros, búsqueda de patrones en el textoEdición de archivos de configuración, reemplazo de texto en varios archivos

Ejemplo:

  • Usando greppara buscar “error” en log.txt:
grep 'error' log.txt
  • Usando sedpara reemplazar “error” con “advertencia” en log.txt:
sed 's/error/warning/g' log.txt

¿Cómo eliminar una línea vacía usando sed?

Para eliminar líneas vacías de un archivo, utilice el siguiente sedcomando:

sed '/^$/d' file.txt

Explicación:

  • ^$: Coincide con líneas vacías (líneas sin caracteres).
  • d:Elimina las líneas coincidentes.

Ejemplo:

Antes de ejecutar el comando, un archivo podría verse así:

line 1

line 2

line 3

Después de ejecutar el comando:

sed '/^$/d' file.txt

La salida será:

Outputline 1
line 2
line 3

Stephen Dove
Comments

April 27, 2025

Cómo crear una aplicación Web usando Flask en Python 3

Introducción

Flask es un marco web de Python pequeño y ligero que proporciona herramientas y funciones útiles que hacen que crear aplicaciones web en Python sea más fácil. Ofrece a los desarrolladores flexibilidad y un marco más accesible para los nuevos desarrolladores ya que puede crear una aplicación web rápidamente usando únicamente un archivo Python. Flask también es extensible y no fuerza una estructura de directorio concreta ni requiere código estándar complicado antes de iniciarse.

Como parte de este tutorial, usará el kit de herramientas Bootstrap para dar estilo a su aplicación, para que sea más atractiva visualmente. Bootstrap le ayudará a incorporar páginas web reactivas en su aplicación web para que también funcione bien en navegadores móviles sin tener que escribir su propio código HTML, CSS y JavaScript para conseguir estos objetivos. El kit de herramientas le permitirá centrarse en aprender cómo funciona Flask.

Flask utiliza el motor de plantillas Jinja para crear dinámicamente páginas HTML usando conceptos Python familiares como variables, bucles, listas, etcétera. Usará estas plantillas como parte de este proyecto.

En este tutorial, creará un pequeño blog web usando Flask y SQLite en Python 3. Los usuarios de la aplicación pueden ver todas las entradas del blog en su base de datos y hacer clic sobre el título de una entrada para ver su contenido, con la capacidad de añadir una nueva publicación a la base de datos y editar o eliminar una entrada existente.

Requisitos previos

Antes de comenzar con esta guía, necesitará lo siguiente:

  • Un entorno de programación Python 3, siguiendo el tutorial para su distribución en la serie Cómo instalar y configurar un entorno de programación local para Python 3 para su equipo local. En este tutorial, llamaremos al directorio de nuestro proyecto flask_blog.
  • Comprender los conceptos de Python 3, como tipos de datos, instrucciones condicionales, bucles for, funciones y otros conceptos similares. Si no está familiarizado con Python, consulte nuestra serie Cómo codificar en Python 3.

Paso 1: Instalar Flask

En este paso, activará su entorno Python e instalará Flask usando el instalador de paquetes pip.

Si aún no ha activado su entorno de programación, asegúrese de que está en el directorio de su proyecto (flask_blog) y utilice el siguiente comando para activar el entorno:

source env/bin/activate

Una vez activado su entorno de programación, su línea de comandos ahora tendrá un prefijo env que puede tener el siguiente aspecto:



Este prefijo es una indicación de que el entorno env está activo actualmente, y puede tener otro nombre dependiendo de cómo lo llamó durante la creación.

Nota: Puede utilizar Git, un sistema de control de versiones, para administrar y realizar un seguimiento de forma efectiva del proceso de desarrollo de su proyecto. Para aprender cómo usar Git, es posible que desee consultar nuestro artículo Introducción a la instalación de Git, uso y ramificaciones.

Si está usando Git, es una buena idea ignorar el recién creado directorio env en su archivo .gitignore para evitar realizar un seguimiento de los archivos no relacionados con el proyecto.

Ahora, instalará los paquetes Python y aislará el código de su proyecto de la instalación del sistema principal de Python. Hará esto usando pip y python.

Para instalar Flask, ejecute el siguiente comando:

pip install flask

Una vez que se complete la instalación, ejecute el siguiente comando para confirmar la instalación:

python -c "import flask; print(flask.__version__)"

Utiliza la interfaz de la línea de comandos python con la opción -c para ejecutar el código Python. A continuación, importa el paquete flask con import flask; luego imprime la versión de Flask, que encontrará a través de la variable flask._version_.

El resultado será un número de versión similar al siguiente:

Output1.1.2

Ha creado la carpeta del proyecto, un entorno virtual, e instalado Flask. Ahora está listo para configurar su aplicación básica.

Paso 2: Crear una aplicación básica

Ahora que tiene su entorno de programación configurado, comenzará a usar Flask. En este paso, creará una pequeña aplicación web dentro de un archivo Python, y la ejecutará para iniciar el servidor, que mostrará cierta información en el navegador.

En su directorio flask_blog, abra un archivo llamado hello.py para su edición; para ello utilice nano o su editor de texto favorito:

nano hello.py

Este archivo hello.py servirá como ejemplo mínimo de cómo gestionar solicitudes HTTP. Dentro, importará el objeto Flask, y creará una función que devuelva una respuesta HTTP. Escriba el siguiente código dentro de hello.py:

flask_blog/hello.py

from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello():
    return 'Hello, World!'

En el bloque de código anterior, primero importa el objeto Flask desde el paquete flask. A continuación lo usará para crear su instancia de aplicación Flask con el nombre app. Pasa la variable especial __name__ que alberga el nombre del módulo Pyhthon actual. Se utiliza para indicar a la instancia dónde está ubicada. Necesitará hacerlo porque Flask configura algunas rutas en segundo plano.

Una vez que cree la instancia app, la utiliza para gestionar las solicitudes web entrantes y enviar respuestas al usuario. @app.route es un decorador que convierte una función Python regular en una función vista de Flask, que convierte el valor de devolución de la función en una respuesta HTTP que se mostrará mediante un cliente HTTP, como un navegador web. Pasa el valor '/' a @app.route() para indicar que esta función responderá a las solicitudes web para la URL /, que es la URL principal.

La función de vista hello() devuelve la cadena 'Hello, World!'​​ como respuesta.

Guarde y cierre el archivo.

Para ejecutar su aplicación web, primero indicará a Flask dónde encontrar la aplicación (el archivo hello.py en su caso) con la variable de entorno FLASK_APP:

export FLASK_APP=hello

A continuación, ejecútela en modo de desarrollo con la variable de entorno FLASK_ENV:

export FLASK_ENV=development

Por último, ejecute la aplicación usando el comando flask run:

flask run

Una vez que la aplicación se esté ejecutando, el resultado será algo similar a esto:

Output * Serving Flask app "hello" (lazy loading)
 * Environment: development
 * Debug mode: on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 813-894-335

El resultado anterior tiene varias informaciones, como:

  • El nombre de la aplicación que está ejecutando.
  • El entorno en el cual se ejecuta la aplicación.
  • Debug mode: on significa que el depurador de Flask se está ejecutando. Esto es útil durante el desarrollo porque nos proporciona mensajes de error detallados cuando algo va mal, lo que hace que sea más fácil resolver los problemas.
  • La aplicación se ejecuta localmente sobre la URL http://127.0.0.1:5000/, 127.0.0.1 es la IP que representa el localhost de su equipo y :5000 es el número de puerto.

Abra un navegador y escriba la URL http://127.0.0.1:5000; recibirá la cadena Hello, World! como respuesta. Esto confirma que su aplicación se está ejecutando correctamente.

Advertencia Flask utiliza un servidor web sencillo para presentar nuestra aplicación en un entorno de desarrollo, lo que también significa que el depurador de Flask se ejecuta para hacer que sea más fácil ver los errores. Este servidor de desarrollo no debería usarse en una implementación de producción. Consulte la página Opciones de implementación en la documentación de Flask para obtener más información; también puede consultar este tutorial de Implementación Flask.

Ahora puede dejar el servidor de desarrollo en ejecución en el terminal y abrir otra ventana del terminal. Vaya a la carpeta del proyecto donde está hello.py, active el entorno virtual, establezca las variables del entorno FLASK_ENV y FLASK_APP y continúe a los siguientes pasos. (Estos comandos se han enumerado antes en este paso).

Nota: Cuando abra un nuevo terminal, es importante recordar activar el entorno virtual y configurar las variables de entorno FLASK_ENV y FLASK_APP.

Mientras un servidor de desarrollo de la aplicación de Flask esté ejecutándose, no es posible ejecutar otra aplicación Flask con el mismo comando flask run. Esto es porque flask run utiliza el número de puerto 5000 por defecto, y una vez utilizado, no está disponible para ejecutar otra aplicación, de forma que recibiría un error similar al siguiente:

OutputOSError: [Errno 98] Address already in use

Para resolver este problema, detenga el servidor que se está ejecutando actualmente mediante CTRL+C, luego ejecute flask run de nuevo, o si desea que ambos se ejecuten a la vez, puede pasar un número de puerto diferente al argumento -p; por ejemplo, para ejecutar otra aplicación en el puerto 5001 utilice el siguiente comando:

flask run -p 5001

Ahora tiene una aplicación web Flask pequeña. Ha ejecutado su aplicación y mostrado información en el navegador web. A continuación, utilizará los archivos HTML en su aplicación.

Paso 3: Usar plantillas HTML

Actualmente, su aplicación solo muestra un mensaje sencillo sin HTML. Las aplicaciones web utilizan principalmente HTML para mostrar información al visitante, de forma que ahora trabajará para incorporar archivos HTML en su aplicación, que puede ser mostrada en el navegador web.

Flask proporciona una función de ayuda render_template() que permite el uso del motor de plantillas Jinja. Esto hará que gestionar HTML sea mucho más fácil escribiendo su código HTML en archivos .html, además de utilizar la lógica en su código HTML. Usará estos archivos HTML, (plantillas), para crear todas las páginas de su aplicación, de igual forma que la página principal donde mostrará las entradas actuales del blog, la página de la entrada del blog, la página donde el usuario puede añadir una nueva entrada, etcétera.

En este paso, creará su aplicación Flask principal en un nuevo archivo.

Primero, en su directorio flask_blog, utilice nano o su editor de texto favorito para crear y editar su archivo app.py. Éste albergará todo el código que usará para crear la aplicación de blog:

nano app.py

En este nuevo archivo, importará el objeto Flask para crear una instancia de aplicación Flask, como hizo antes. También importará la función de ayuda render_template() que le permite representar archivos de plantilla HTML que existen en la carpeta templates que está a punto de crear. El archivo tendrá una función de vista única que será responsable de gestionar las solicitudes a la ruta principal /. Añada el siguiente contenido:

flask_blog/app.py

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

La función de vista index() devuelve el resultado de invocar render_template() con index.html como argumento; esto indica a render_template() que busque un archivo llamado index.html en la carpeta templates. La carpeta y el archivo no existen aún, y recibirá un error si ejecutase la aplicación en este momento. De todas formas la va a ejecutar, para que se familiarice con esta excepción que se encuentra comúnmente. Luego lo resolverá creando la carpeta y archivo necesarios.

Guarde el archivo y ciérrelo.

Detenga el servidor de desarrollo en su otro terminal que ejecuta la aplicación hello con CTRL+C.

Antes de ejecutar la aplicación, asegúrese de especificar correctamente el valor para la variable de entorno FLASK_APP, ya que ahora no está usando la aplicación hello.

export FLASK_APP=app
flask run

Al abrir la URL http://127.0.0.1:5000 en su navegador, se mostrará la página del depurador informándole de que no se ha encontrado la plantilla index.html. La línea de código principal en el código responsable de este error se resaltará. En este caso, es la línea return render_template('index.html').

Si hace clic en esta línea, el depurador revelará más código de forma que tenga más contexto para ayudarle a resolver el problema.

El Depurador de Flask

Para solucionar este error, cree un directorio llamado templates dentro de su directorio flask_blog. Dentro de él, abra un archivo llamado index.html para su edición:

mkdir templates
nano templates/index.html

A continuación, añada el siguiente código HTML dentro de index.html:

flask_blog/templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>FlaskBlog</title>
</head>
<body>
   <h1>Welcome to FlaskBlog</h1>
</body>
</html>

Guarde el archivo y utilice su navegador para navegar a http://127.0.0.1:500 de nuevo, o actualice la página. Esta vez, el navegador debería mostrar el texto Welcome to FlaskBlog en una etiqueta <h1>.

Además de la carpeta templates, las aplicaciones web de Flask también tienen normalmente una carpeta estática para albergar archivos, como los archivos CSS, archivos JavaScript, e imágenes que utiliza la aplicación.

Puede crear un archivo de hoja de estilo style.css para añadir CSS a su aplicación. Primero, cree un directorio llamado static dentro de su directorio flask_blog principal:

mkdir static

Luego cree otro directorio llamado css dentro del directorio static para albergar los archivos .css. Esto normalmente se hace para organizar archivos estáticos en carpetas dedicadas y, en consecuencia, los archivos JavaScript dentro de un directorio llamado js, las imágenes se ponen en un directorio llamado images (o img), etcétera. El siguiente comando creará el directorio css dentro del directorio static:

mkdir static/css

Luego abra un archivo style.css dentro del directorio css para su edición:

nano static/css/style.css

Añada la siguiente regla CSS a su archivo style.css:

flask_blog/static/css/style.css

h1 {
    border: 2px #eee solid;
    color: brown;
    text-align: center;
    padding: 10px;
}

El código CSS añadirá un borde, cambiará el color a marrón, centrará el texto y añadirá un pequeño relleno a las etiquetas <h1>.

Guarde y cierre el archivo.

A continuación, abra el archivo de plantilla index.html para su edición:

nano templates/index.html

Añadirá un enlace al archivo style.css dentro de la sección <head> del archivo de plantilla index.html:

flask_blog/templates/index.html

. . .
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="{{ url_for('static', filename= 'css/style.css') }}">
    <title>FlaskBlog</title>
</head>
. . .

Aquí utiliza la función de ayuda url_for() para generar la ubicación apropiada del archivo. El primer argumento especifica que está vinculando a un archivo estático, y el segundo argumento es la ruta del archivo dentro del directorio estático.

Guarde y cierre el archivo.

Tras actualizar la página de índice de su aplicación, observará que el texto Welcome to FlaskBlog es ahora marrón, está centrado y se encuadra dentro de un borde.

Puede utilizar el lenguaje CSS para dar estilo a la aplicación y hacer que sea más atractiva usando su propio diseño. Sin embargo, si no es un diseñador web, o no está familiarizado con CSS, puede usar el kit de herramientas Bootstrap, que ofrece componentes fáciles de usar para dar estilo a su aplicación. En este proyecto, usaremos Bootstrap.

Quizá haya imaginado que crear otra plantilla HTML significará repetir la mayoría del código HTML que ya escribió en la plantilla index.html. Puede evitar la repetición innecesaria de código con la ayuda de un archivo de plantilla base, desde el cual heredarán todos sus archivos HTML. Consulte Herencia de plantillas en Jinja para obtener más información.

Para crear una plantilla base, primero cree un archivo llamado base.html dentro de su directorio templates:

nano templates/base.html

Escriba el siguiente código en su plantilla base.html:

flask_blog/templates/base.html

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

    <title>{% block title %} {% endblock %}</title>
  </head>
  <body>
    <nav class="navbar navbar-expand-md navbar-light bg-light">
        <a class="navbar-brand" href="{{ url_for('index')}}">FlaskBlog</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarNav">
            <ul class="navbar-nav">
            <li class="nav-item active">
                <a class="nav-link" href="#">About</a>
            </li>
            </ul>
        </div>
    </nav>
    <div class="container">
        {% block content %} {% endblock %}
    </div>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
  </body>
</html>

Guarde y cierre el archivo una vez que haya terminado de editarlo.

La mayor parte del código en el bloque anterior es HTML estándar y el código necesario para Bootstrap. Las etiquetas <meta> proporcionan información para el navegador web, la etiqueta <link> enlaza los archivos CSS de Boostrap y las etiquetas <script> son enlaces a código JavaScript que permite algunas funciones adicionales de Boostrap; consulte la documentación de Boostrap para obtener más información.

Sin embargo, las siguientes partes resaltadas son específicas para el motor de plantillas Jinja:

  • {% block title %} {% endblock %}: un bloque que sirve como marcador de posición para un título. Más adelante lo usará en otras plantillas para dar un título personalizado a cada página de su aplicación sin tener que reescribir toda la sección <head> cada vez.
  • {{ url_for('index')}: una invocación de función que devolverá la URL para la función de vista index(). Esto es diferente a la invocación anterior url_for() que utilizó para vincular a un archivo CSS estático, porque solo requiere un argumento, que es el nombre de la función de vista, y enlaza a la ruta asociada con la función en vez de con un archivo estático.
  • {% block content %} {% endblock %}: otro bloque que se sustituirá por contenido dependiendo de la plantilla secundaria (plantillas que heredan de base.html) que lo anulará.

Ahora que tiene una plantilla base, puede aprovecharla usando la herencia. Abra el archivo index.html:

nano templates/index.html

Sustituya su contenido con lo siguiente:

flask_blog/templates/index.html

{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Welcome to FlaskBlog {% endblock %}</h1>
{% endblock %}

En esta nueva versión de la plantilla index.html, utiliza la etiqueta {% extends %} para que herede de la plantilla base.html. Luego la extiende sustituyendo el bloque content en la plantilla base con lo que está dentro del bloque content en el bloque de código anterior.

Este bloque content contiene una etiqueta <h1> con el texto Welcome to FlaskBlog dentro de un bloque title, que a su vez sustituye el bloque title original en la plantilla base.html con el texto Welcome to FlaskBlog. De esta forma, puede evitar repetir el mismo texto dos veces, ya que funciona como título para la página y como encabezado que aparece bajo la barra de navegación heredada de la plantilla base.

La herencia de plantillas también le ofrece la capacidad de reutilizar el código HTML que tiene en otras plantillas (base.html en este caso), sin tener que repetirlo cada vez que sea necesario.

Guarde y cierre el archivo y actualice la página de índice en su navegador. Verá su página con una barra de navegación y un título con estilo.

Página de índice con Bootstrap

Utilizó plantillas HTML y archivos estáticos en Flask. También ha utilizado Bootstrap para comenzar a refinar el aspecto de su página y una plantilla base para evitar la repetición del código. En el siguiente paso, configurará una base de datos que almacenará los datos de su aplicación.

Paso 4: Configurar la base de datos

En este paso, configurará una base de datos para almacenar los datos, es decir, las entradas del blog para su aplicación. También completará la base de datos con algunas entradas de ejemplo.

Usará un archivo de base de datos SQLite para guardar sus datos porque el módulo sqlite3, que utilizaremos para interactuar con la base de datos, está disponible en la biblioteca Python. Para obtener más información sobre SQLite, consulte este tutorial.

Primero, ya que los datos de SQLite se guardan en tablas y columnas, y ya que sus datos principalmente son entradas de blog, primero deberá crear una tabla llamada posts con las columnas necesarias. Creará un archivo .sql que contiene comandos SQL para crear la tabla posts con algunas columnas. A continuación usará este archivo para crear la base de datos.

Abra un archivo llamado schema.sql dentro de su directorio flask_blog:

nano schema.sql

Escriba los siguientes comandos SQL dentro de este archivo:

flask_blog/schema.sql

DROP TABLE IF EXISTS posts;

CREATE TABLE posts (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    title TEXT NOT NULL,
    content TEXT NOT NULL
);

Guarde y cierre el archivo.

El primer comando SQL es DROP TABLE IF EXISTS posts;, esto elimina cualquier tabla que exista llamada posts para que no tenga un comportamiento confuso. Observe que esto eliminará todo el contenido que tenga en la base de datos siempre que utilice estos comandos SQL, de forma que asegúrese de no escribir ningún contenido importante en la aplicación web hasta que haya terminado con este tutorial y experimente con el resultado final. A continuación, CREATE TABLE posts se utiliza para crear la tabla posts con las siguientes columnas:

  • id: es un entero que representa una clave primaria. La base de datos asignará un valor único para cada entrada (es decir, una entrada blog).
  • created: la hora en que se creó la entrada de blog. NOT NULL significa que esta columna no debería estar vacía y el valor DEFAULT es el valor CURRENT_TIMESTAMP, que es la hora en la cual la entrada se añadió a la base de datos. Igual que el id, no necesita especificar un valor para esta columna, y que se completará automáticamente.
  • title: el título de la entrada.
  • content: el contenido de la entrada.

Ahora que tiene un esquema SQL en el archivo schema.sql, lo usará para crear la base de datos usando un archivo Python que generará un archivo base de datos .db de SQLite. Abra un archivo llamado init_db.py dentro del directorio flask_blog usando su editor preferido:

nano init_db.py

Y luego añada el siguiente código.

flask_blog/init_db.py

import sqlite3

connection = sqlite3.connect('database.db')


with open('schema.sql') as f:
    connection.executescript(f.read())

cur = connection.cursor()

cur.execute("INSERT INTO posts (title, content) VALUES (?, ?)",
            ('First Post', 'Content for the first post')
            )

cur.execute("INSERT INTO posts (title, content) VALUES (?, ?)",
            ('Second Post', 'Content for the second post')
            )

connection.commit()
connection.close()

Primero importe el módulo sqlite3 y luego abra una conexión con el archivo de la base de datos llamada database.db, que se creará una vez que ejecute el archivo Python. Luego utilice la función open() para abrir el archivo schema.sql. A continuación, ejecute su contenido utilizando el método executescript() que ejecuta múltiples instrucciones SQL a la vez, lo que creará la tabla posts. Crea un objeto Cursor que le permite usar su método execute() para ejecutar dos instrucciones SQL INSERT para permitir dos entradas de blog en su tabla posts. Finalmente, confirma los cambios y cierra la conexión.

Guarde y cierre el archivo y a continuación ejecútelo en el terminal usando el comando python:

python init_db.py

Una vez que el archivo termine su ejecución, aparecerá un nuevo archivo llamado database.db en su directorio flask_blog. Esto significa que la configurado correctamente su base de datos.

En el siguiente paso, recuperará las entradas que insertó en su base de datos y las mostrará en la página de inicio de su aplicación.

Paso 5: Mostrar todas las entradas

Ahora que ha configurado su base de datos, puede modificar la función de vista index() para mostrar todas las entradas que tiene en su base de datos.

Abra el archivo app.py para realizar las siguientes modificaciones:

nano app.py

Para su primera modificación, importará el módulo sqlite3 en la parte superior del archivo:

flask_blog/app.py

import sqlite3
from flask import Flask, render_template

. . .

A continuación, creará una función que cree una conexión de base de datos y la devolverá. Añádala directamente tras las importaciones:

flask_blog/app.py

. . .
from flask import Flask, render_template

def get_db_connection():
    conn = sqlite3.connect('database.db')
    conn.row_factory = sqlite3.Row
    return conn

. . .

Esta función get_db_connection() abra una conexión con el archivo de base de datos database.db, y luego establece el atributo row_factory a sqlite3. Row para poder tener acceso basado en nombre a las columnas. Esto significa que la conexión con la base de datos devolverá filas que se comportan como diccionarios Python regulares. Por último, la función devuelve el objeto de conexión conn que usará para acceder a la base de datos.

Tras definir la función get_db_connection, modifique la función index() para que tenga el siguiente aspecto:

flask_blog/app.py

. . .

@app.route('/')
def index():
    conn = get_db_connection()
    posts = conn.execute('SELECT * FROM posts').fetchall()
    conn.close()
    return render_template('index.html', posts=posts)

En esta nueva versión de la función index(), primero abre una conexión de base de datos usando la función get_db_connection() que definió antes. A continuación, ejecuta una consulta SQL para seleccionar todas las entradas de la tabla post. Implementa el método fetchall() para recuperar todas las filas del resultado de la consulta. Esto devolverá una lista de las entradas que insertó en la base de datos en el paso anterior.

Cierra la conexión con la base de datos usando el método close() y devuelve el resultado de representar la plantilla index.html. También pasará el objeto posts como argumento, que contiene los resultados que obtuvo de la base de datos; esto le permitirá acceder a las entradas del blog en la plantilla index.html.

Con estas modificaciones implementadas, guarde y cierre el archivo app.py.

Ahora que ha pasado las entradas que recuperó de la base de datos a la plantilla index.html, puede usar un bucle for para mostrar cada entrada en su página de índice.

Abra el archivo index.html:

nano templates/index.html

A continuación, modifíquelo como sigue:

flask_blog/templates/index.html

{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Welcome to FlaskBlog {% endblock %}</h1>
    {% for post in posts %}
        <a href="#">
            <h2>{{ post['title'] }}</h2>
        </a>
        <span class="badge badge-primary">{{ post['created'] }}</span>
        <hr>
    {% endfor %}
{% endblock %}

Aquí, la sintaxis {% for post in posts %} es un bucle for Jinja, que es similar a un bucle for Python, excepto que tiene que ser cerrado posteriormente con la sintaxis {% endfor %}. Utiliza esta sintaxis para realizar un bucle sobre cada elemento en la lista posts que se pasó por la función index() en la línea return render_template('index.html', posts=posts). Dentro de este bucle for, muestra el título de la entrada en un encabezado <h2> dentro de una etiqueta <a> (más tarde utilizará esta etiqueta para vincular con cada entrada individualmente).

Muestra el título utilizando un delimitador variable literal ({{ ... }}). Recuerde que post será un objeto similar a un diccionario, para que pueda acceder al título de la entrada con post['title']​​​. También muestra la fecha de creación de la entrada usando el mismo método.

Una vez que haya terminado de editar el archivo, guarde y ciérrelo. Luego navegue a la página de índice en su navegador. Verá las dos entradas que añadió a la base de datos en su página.

Página de índice con entradas mostradas

Ahora que ha modificado la función de vista index() para mostrar todas las entradas que tiene en la base de datos en la página de inicio de su aplicación, pasará a mostrar cada entrada en una única página y permitirá que los usuarios vinculen a cada entrada individual.

Paso 6: Mostrar una entrada única

En este paso, creará una nueva ruta Flask con una función de vista y una nueva plantilla HTML para mostrar una entrada de blog individual por su ID.

Al final de este paso, la URL http://127.0.0.1:5000/1 será una página que muestra la primera entrada (porque tiene el ID 1). La URL http://127.0.0.1:5000/ID mostrará la entrada con el número ID asociado si existe.

Abra app.py para su edición:

nano app.py

Ya que necesitará obtener una entrada de blog por su ID de la base de datos en múltiples ubicación más adelante en este proyecto, creará una función independiente llamada get_post(). Puede invocarla pasándole un ID y recibiendo la entrada de blog asociada con el ID proporcionado, o hacer que Flask responsa con un mensaje 404 Not Found si la entrada de blog no existe.

Para responder con una página 404, deberá importar la función abort() desde la biblioteca Wekzeug, que se instaló junto con Flask en la parte superior del archivo:

flask_blog/app.py

import sqlite3
from flask import Flask, render_template
from werkzeug.exceptions import abort

. . .

A continuación, añada la función get_post() justo tras la función get_db_connection() que creó en el paso anterior:

flask_blog/app.py

. . .

def get_db_connection():
    conn = sqlite3.connect('database.db')
    conn.row_factory = sqlite3.Row
    return conn


def get_post(post_id):
    conn = get_db_connection()
    post = conn.execute('SELECT * FROM posts WHERE id = ?',
                        (post_id,)).fetchone()
    conn.close()
    if post is None:
        abort(404)
    return post

. . .

Esta nueva función tiene el argumento post_id que determina qué entrada de blog recuperar.

Dentro de la función, utiliza la función get_db_connection() para abrir una conexión de base de datos y ejecutar una consulta SQL para obtener la entada de blog asociada con el valor post_id dado. Añade el método fetchone() para obtener el resultado y almacenarlo en la variable post. Luego, cierre la conexión. Si la variable post tiene el valor None, lo que significa que no se ha encontrado ningún resultado en la base de datos, utiliza la función abort() que importó anteriormente para responder con un código de error 404 y la función terminará la ejecución. Si, sin embargo, se encuentra una entrada, devuelve el valor de la variable post.

A continuación, añada la siguiente función de vista al final del archivo app.py:

flask_blog/app.py

. . .

@app.route('/<int:post_id>')
def post(post_id):
    post = get_post(post_id)
    return render_template('post.html', post=post)

En esta nueva función de vista, añade una regla de variable <int:post_id> para especificar que la parte tras la barra (/) es un entero positivo (marcado con el conversor int) que necesita para acceder en su función de vista. Flask reconoce esto y pasa su valor al argumento de palabra clave post_id de su función de vista post(). A continuación, utiliza la función get_post() para obtener la entrada de blog asociada con el ID especificado y almacenar el resultado en la variable post, que pasa por una plantilla post.html que pronto creará.

Guarde el archivo app.py y abra un nuevo archivo de plantilla post.html para su edición:

nano templates/post.html

Escriba el siguiente código en este nuevo archivo post.html. Esto será similar al archivo index.html, excepto que solo mostrará una única entrada además de mostrar el contenido de la entrada:

flask_blog/templates/post.html

{% extends 'base.html' %}

{% block content %}
    <h2>{% block title %} {{ post['title'] }} {% endblock %}</h2>
    <span class="badge badge-primary">{{ post['created'] }}</span>
    <p>{{ post['content'] }}</p>
{% endblock %}

Añade el bloque title que definió en la plantilla base.html para hacer que el título de la página refleje el título de la entrada que se muestra en un encabezado <h2> al mismo tiempo.

Guarde y cierre el archivo.

Ahora puede navegar a la siguiente URL para ver las dos entradas que tiene en su base de datos, junto con una página que indica al usuario que no se encontró la entrada del blog solicitada (ya que no hay una entrada con el número de ID 3 hasta ahora):

http://127.0.0.1:5000/1
http://127.0.0.1:5000/2
http://127.0.0.1:5000/3

Volviendo a la página de índice, creará cada enlace al título de la entrada a su página respectiva. Hará esto usando la función url_for(). Primero, abra la plantilla index.html para su edición:

nano templates/index.html

A continuación cambie el valor del atributo href de # a {{ url_for('post', post_id=post['id']) }} de forma que el bucle for tendrá el siguiente aspecto:

flask_blog/templates/index.html

{% for post in posts %}
    <a href="{{ url_for('post', post_id=post['id']) }}">
        <h2>{{ post['title'] }}</h2>
    </a>
    <span class="badge badge-primary">{{ post['created'] }}</span>
    <hr>
{% endfor %}

Aquí, pasa 'post' a la función url_for() como primer argumento. Este es el nombre de la función de vista post() y ya que acepta un argumento post_id, le da el valor post['id']. La función url_for() devolverá la URL adecuada para cada entrada según su ID.

Guarde y cierre el archivo.

Los enlaces en la página de índice ahora funcionarán como se espera. Con esto, ha terminado de crear la parte de la aplicación responsable de mostrar las entradas de blog en su base de datos. A continuación, añadirá la capacidad de crear, editar y eliminar entradas de blog en su aplicación.

Paso 7: Modificar entradas

Ahora que ha terminado de mostrar las entradas de blog que están presentes en la base de datos en la aplicación web, deberá permitir a los usuarios de su aplicación escribir nuevas entradas de blog y añadirlas a la base de datos, editar las existentes y eliminar las entradas de blog innecesarias.

Crear una nueva entrada

Hasta este momento, tiene una aplicación que muestra las entradas en su base de datos pero no ofrece ninguna forma de añadir una nueva entrada a menos que conecte directamente con la base de datos SQLite y añada una manualmente. En esta sección, creará una página sobre la cual podrá crear una entrada proporcionando su título y contenido.

Abra el archivo app.py para su edición:

nano app.py

Primero, importará lo siguiente desde el marco Flask:

  • El objeto global request para acceder a los datos de solicitud entrantes que se enviarán a través de un formato HTML.
  • La función url_for() para generar URLs.
  • La función flash() para mostrar un mensaje cuando se procesa una solicitud.
  • La función redirect() para redirigir al cliente a una ubicación diferente.

Añada las importaciones a su archivo de la siguiente forma:

flask_blog/app.py

import sqlite3
from flask import Flask, render_template, request, url_for, flash, redirect
from werkzeug.exceptions import abort

. . .

La función flash() almacena los mensajes mostrados en la sesión del navegador del cliente, lo que requiere configurar una clave secreta. Esta clave secreta se utiliza para proteger las sesiones, lo que permite a Flask recordar la información de una solicitud a la otra, como pasar desde la nueva página de entrada a la página de índice. El usuario puede acceder a la información almacenada en la sesión, pero no puede modificarla a menos que tenga la clave secreta, de forma que nunca permita que nadie acceda a la clave secreta. Consulte la documentación de Flask para sesiones para obtener más información.

Para establecer una_ clave_ secreta, añadirá una configuración SECRET_KEY a su aplicación a través del objeto app.config. Añádala directamente siguiendo la definición app antes de definir la función de vista index():

flask_blog/app.py

. . .
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your secret key'


@app.route('/')
def index():
    conn = get_db_connection()
    posts = conn.execute('SELECT * FROM posts').fetchall()
    conn.close()
    return render_template('index.html', posts=posts)

. . .

Recuerde que la clave secreta debería ser una cadena aleatoria larga.

Tras establecer una clave secreta, creará una función de vista que mostrará una plantilla que muestra un formulario que puede completar para crear una nueva entrada de blog. Añada esta nueva función en la parte inferior del archivo:

flask_blog/app.py

. . .

@app.route('/create', methods=('GET', 'POST'))
def create():
    return render_template('create.html')

Esto crea una ruta /create que acepta las solicitudes GET y POST. Las solicitudes GET se aceptan por defecto. También acepta las solicitudes POST que se envía el navegador cuando se envían formularios. Pasará un tuple con los tipos de solicitudes aceptadas al argumento methods del decorador @app.route().

Guarde y cierre el archivo.

Para crear la plantilla, abra un archivo llamado create.html dentro de su carpeta templates:

nano templates/create.html

Añada el siguiente código dentro de este nuevo archivo:

flask_blog/templates/create.html

{% extends 'base.html' %}

{% block content %}
<h1>{% block title %} Create a New Post {% endblock %}</h1>

<form method="post">
    <div class="form-group">
        <label for="title">Title</label>
        <input type="text" name="title"
               placeholder="Post title" class="form-control"
               value="{{ request.form['title'] }}"></input>
    </div>

    <div class="form-group">
        <label for="content">Content</label>
        <textarea name="content" placeholder="Post content"
                  class="form-control">{{ request.form['content'] }}</textarea>
    </div>
    <div class="form-group">
        <button type="submit" class="btn btn-primary">Submit</button>
    </div>
</form>
{% endblock %}

La mayor parte de este código es HTML estándar. Mostrará un cuadro de entrada para el título de la entrada, un área de texto para el contenido de la entrada y un botón para enviar el formulario.

El valor de la entrada del título de la entrada es {{ request.form['title'] }},​​​ y el área de texto tiene el valor {{ request.form['content'] }}. Esto se hace para que los datos que introduce no se pierdan si algo sale mal. Por ejemplo, si escribe una entrada larga y olvida darle un título, se mostrará un mensaje que le informa de que el título es necesario. Esto sucederá sin perder la entrada que escribió ya que se almacenará en el objeto global request al que tiene acceso en sus plantillas.

Ahora, con el servidor de desarrollo en ejecución, utilice su navegador para navegar a la ruta /create:

http://127.0.0.1:5000/create

Verá una página Create a New Post con un cuadro para un título y contenido:

Crear una nueva página de entrada

Este formulario envía una solicitud POST a su función de vista create(). Sin embargo, aún no hay ningún código para gestionar una solicitud POST en la función, de forma que no sucederá nada tras completar el formulario y enviarlo.

Gestionará la solicitud POST entrante cuando se envía un formulario. Lo hará dentro de la función de vista create(). Puede gestionar por separado la solicitud POST comprobando el valor de request.method. Cuando su valor se establece a 'POST', significa que la solicitud es una solicitud POST. Luego extraerá los datos enviados, los validará y los insertará en su base de datos.

Abra el archivo app.py para su edición:

nano app.py

Modifique la función de vista create() para que tenga exactamente el siguiente aspecto:

flask_blog/app.py

. . .

@app.route('/create', methods=('GET', 'POST'))
def create():
    if request.method == 'POST':
        title = request.form['title']
        content = request.form['content']

        if not title:
            flash('Title is required!')
        else:
            conn = get_db_connection()
            conn.execute('INSERT INTO posts (title, content) VALUES (?, ?)',
                         (title, content))
            conn.commit()
            conn.close()
            return redirect(url_for('index'))

    return render_template('create.html')

En la instrucción if asegura que el código que le sigue solo se ejecuta cuando la solicitud es una solicitud POST a través de la comparativa request.method == 'POST'.

A continuación, extrae el título enviado y el contenido desde el objeto request.form que le proporciona acceso a los datos del formulario en la solicitud. Si no se proporciona el título, la condición if not title se cumplirá, mostrando un mensaje al usuario informándole de que el título es obligatorio. Si, por otro lado, se proporciona el título, abrirá una conexión con la función get_db_connection() e insertará el título y el contenido que recibió en la tabla posts.

Luego confirma los cambios en la base de datos y cierra la conexión. Tras añadir la entrada de blog a la base de datos, redirige al cliente a la página de índice usando la función redirect() pasándole la URL generada por la función url_for() con el valor 'index' como argumento.

Guarde y cierre el archivo.

Ahora, navegue a la ruta /create usando su navegador web:

http://127.0.0.1:5000/create

Complete el formulario con un título y algo de contenido. Una vez que envíe el formulario, verá la nueva entrada listada en la página de índice.

Por último, mostrará los mensajes generados y añadirá un enlace a la barra de navegación en la plantilla base.html para tener un acceso fácil a esta nueva página. Abra el archivo de plantilla:

nano templates/base.html

Edite el archivo añadiendo una nueva etiqueta <li> tras el enlace About dentro de la etiqueta <nav>. A continuación, añada un nuevo bucle for directamente sobre el bloque content para mostrar los mensajes generados bajo la barra de navegación. Estos mensajes están disponibles en la función especial get_flashed_messages() que Flask ofrece:

flask_blog/templates/base.html

<nav class="navbar navbar-expand-md navbar-light bg-light">
    <a class="navbar-brand" href="{{ url_for('index')}}">FlaskBlog</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarNav">
        <ul class="navbar-nav">
        <li class="nav-item">
            <a class="nav-link" href="#">About</a>
        </li>
        <li class="nav-item">
            <a class="nav-link" href="{{url_for('create')}}">New Post</a>
        </li>
        </ul>
    </div>
</nav>
<div class="container">
    {% for message in get_flashed_messages() %}
        <div class="alert alert-danger">{{ message }}</div>
    {% endfor %}
    {% block content %} {% endblock %}
</div>

Guarde y cierre el archivo. La barra de navegación ahora tendrá un elemento New Post que enlaza a la ruta /create.

Editar una entrada

Para que un blog esté actualizado, deberá poder editar sus entradas existentes. Esta sección le guiará en la creación de una nueva página en su aplicación para simplificar el proceso de editar una entrada.

Primero, añadirá una nueva ruta al archivo app.py. Su función de vista recibirá el ID de la entrada que debe ser editada, la URL estará en el formato /post_id/edit con la variable post_id siendo el ID de la entrada. Abra el archivo app.py para su edición:

nano app.py

A continuación, añada la siguiente función de vista edit() al final del archivo. Editar una entrada existente es similar a crear una nueva, de forma que esta función de vista será similar a la función de vista create():

flask_blog/app.py

. . .

@app.route('/<int:id>/edit', methods=('GET', 'POST'))
def edit(id):
    post = get_post(id)

    if request.method == 'POST':
        title = request.form['title']
        content = request.form['content']

        if not title:
            flash('Title is required!')
        else:
            conn = get_db_connection()
            conn.execute('UPDATE posts SET title = ?, content = ?'
                         ' WHERE id = ?',
                         (title, content, id))
            conn.commit()
            conn.close()
            return redirect(url_for('index'))

    return render_template('edit.html', post=post)

La entrada que edita viene determinada por la URL y Flask pasará el número de ID a la función edit() a través del argumento id. Añade este valor a la función get_post() para recuperar la entrada asociada con el ID proporcionado desde la base de datos. Los nuevos datos vendrán en una solicitud POST, que se gestiona dentro de la condición if request.method == 'POST'.

Igual que cuando creó una nueva entrada, primero extrae los datos del objeto request.form, luego muestra un mensaje si el título tiene un valor vacío, de lo contrario, abre una conexión con la base de datos. Luego actualiza la tabla posts estableciendo un nuevo título y nuevo contenido donde el ID de la entrada en la base de datos es igual al ID que estaba en la URL.

En el caso de una solicitud GET, representa una plantilla edit.html pasando la variable post que alberga el valor devuelto de la función get_post(). Usará esto para mostrar el título existente y el contenido en la página de edición.

Guarde y cierre el archivo, y cree una nueva plantilla edit.html:

nano templates/edit.html

Escriba el siguiente código dentro de este nuevo archivo:

flask_blog/templates/edit.html

{% extends 'base.html' %}

{% block content %}
<h1>{% block title %} Edit "{{ post['title'] }}" {% endblock %}</h1>

<form method="post">
    <div class="form-group">
        <label for="title">Title</label>
        <input type="text" name="title" placeholder="Post title"
               class="form-control"
               value="{{ request.form['title'] or post['title'] }}">
        </input>
    </div>

    <div class="form-group">
        <label for="content">Content</label>
        <textarea name="content" placeholder="Post content"
                  class="form-control">{{ request.form['content'] or post['content'] }}</textarea>
    </div>
    <div class="form-group">
        <button type="submit" class="btn btn-primary">Submit</button>
    </div>
</form>
<hr>
{% endblock %}

Guarde y cierre el archivo.

Este código sigue el mismo patrón excepto por la sintaxis {{ request.form['title'] or post['title'] }} y {{ request.form['content'] or post['content'] }}. Esto muestra los datos guardados en la solicitud si existe, de lo contrario, muestra los datos de la variable post que se pasó a la plantilla que contiene los datos actuales de la base de datos.

Ahora, navegue a la siguiente URL para editar la primera entrada:

http://127.0.0.1:5000/1/edit

Verá una página Edit “First Post”.

Editar la página de una entrada

Edite la entrada y envíe el formulario, luego asegúrese de que la entrada se ha actualizado.

Ahora necesita añadir un enlace que apunte a la página de edición para cada entrada en la página de índice. Abra el archivo de plantilla index.html:

nano templates/index.html

Edite el archivo para que tenga exactamente el siguiente aspecto:

flask_blog/templates/index.html

{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Welcome to FlaskBlog {% endblock %}</h1>
    {% for post in posts %}
        <a href="{{ url_for('post', post_id=post['id']) }}">
            <h2>{{ post['title'] }}</h2>
        </a>
        <span class="badge badge-primary">{{ post['created'] }}</span>
        <a href="{{ url_for('edit', id=post['id']) }}">
            <span class="badge badge-warning">Edit</span>
        </a>
        <hr>
    {% endfor %}
{% endblock %}

Guarde y cierre el archivo.

Aquí añade una etiqueta <a> para enlazar a la función de vista edit(), pasando el valor post['id'] al enlace para editar la página de cada entrada con el enlace Edit.

Eliminar una entrada

A veces, no es necesario que una entrada siga estando disponible públicamente, y por eso la funcionalidad de eliminar una entrada es crucial. En este paso, añadirá la funcionalidad de eliminación a su aplicación.

Primero, añadirá una nueva ruta /ID/delete que acepta solicitudes POST, de forma similar a la función de vista edit(). Su nueva función de vista delete() recibirá el ID de la entrada que será eliminada de la URL. Abra el archivo app.py:

nano app.py

Añada la siguiente función de vista en la parte inferior del archivo:

flask_blog/app.py

# ....

@app.route('/<int:id>/delete', methods=('POST',))
def delete(id):
    post = get_post(id)
    conn = get_db_connection()
    conn.execute('DELETE FROM posts WHERE id = ?', (id,))
    conn.commit()
    conn.close()
    flash('"{}" was successfully deleted!'.format(post['title']))
    return redirect(url_for('index'))

Esta función de vista solo acepta solicitudes POST. Esto significa que navegar a la ruta /ID/delete en su navegador devolverá un error porque los navegadores web van de forma predeterminada a las solicitudes GET.

Sin embargo, puede acceder a esta ruta mediante un formulario que envía una solicitud POST pasando el ID de la entrada que desea eliminar. La función recibirá el valor de ID y lo usará para obtener la entrada de la base de datos con la función get_post().

A continuación, abrirá una conexión de base de datos y ejecutará un comando SQL DELETE FROM para eliminar la entrada. Confirma el cambio en la base de datos y cierra la conexión mientras muestra un mensaje para informar al usuario de que la entrada se eliminó correctamente y redirigirlo a la página de índice.

Observe que no reproduce un archivo de plantilla. Esto es porque añadirá un botón Delete a la página de edición.

Abra el archivo de plantilla edit.html:

nano templates/edit.html

Luego, añada la siguiente etiqueta <form> tras la etiqueta <hr> y directamente antes de la línea {% endblock %}:

flask_blog/templates/edit.html

<hr>

<form action="{{ url_for('delete', id=post['id']) }}" method="POST">
    <input type="submit" value="Delete Post"
            class="btn btn-danger btn-sm"
            onclick="return confirm('Are you sure you want to delete this post?')">
</form>

{% endblock %}

Utiliza el método confirm() para mostrar un mensaje de confirmación antes de enviar la solicitud.

Ahora, navegue de nuevo a la página de edición de una entrada de blog e intente eliminarla:

http://127.0.0.1:5000/1/edit

Al final de este paso, el código fuente de su proyecto tendrá el aspecto del código en esta página.

Con esto, los usuarios de su aplicación pueden escribir nuevas entradas de blog y añadirlas a la base de datos, editar entradas y eliminar las entradas existentes.

Conclusión

Este tutorial ha introducido los conceptos esenciales del marco Flask Python. Ha aprendido a crear una pequeña aplicación web, ejecutarla en un servidor de desarrollo y a permitir al usuario proporcionar datos personalizados a través de parámetros URL y formularios web. También utilizó el motor de plantillas Jinja para reutilizar los archivos HTMP y usar lógica en ellos. Al final de este tutorial, tendrá un blog web completamente funcional que interactúa con una base de datos SQLite para crear, mostrar, editar y eliminar entradas de blog usando el lenguaje Python y las consultas SQL.

Puede seguir desarrollando esta aplicación añadiendo autenticación del usuario de forma que solo los usuarios registrados puedan crear o modificar entradas de blog. También puede añadir comentarios y etiquetas para cada entrada de blog, y añadir subidas de archivos para dar a los usuarios la capacidad de incluir imágenes en la entrada del blog. Consulte la documentación de Flask para obtener más información.

Flask cuenta con muchas extensiones Flask creadas por la comunidad. A continuación verá una lista de extensiones que quizá quiera considerar usar para que su proceso de desarrollo sea más fácil:

  • Flask-Login: gestiona la sesión del usuario y el inicio y cierre de sesión, además de recordar a los usuarios con sesión iniciada.
  • Flask-SQLAlchemy: simplifica el uso de Flask con SQLAlchemy, un kit de herramientas Python SQL y un Asignador relacional de objetos para interactuar con bases de datos SQL.
  • Flask-Mail: ayuda con la tarea de enviar mensajes de correo electrónico en su aplicación Flask.

Stephen Dove
Comments

April 27, 2025

Cómo instalar MySQL en Ubuntu 22.04

Introducción

MySQL es un sistema de gestión de bases de datos de código abierto, comúnmente instalado como parte de la popular pila LAMP (Linux, Apache, MySQL, PHP/Python/Perl). Implementa el modelo relacional y utiliza el Lenguaje de Consulta Estructurado (más conocido como SQL) para gestionar sus datos.

Este tutorial explicará cómo instalar MySQL versión 8.0 en un servidor Ubuntu 22.04. Al completarlo, dispondrá de una base de datos relacional funcional que podrá usar para crear su próximo sitio web o aplicación.

Implemente una base de datos MySQL con un solo clic usando las bases de datos administradas de IsnHosting . Deje que DigitalOcean se encargue del escalado, el mantenimiento y las actualizaciones de su base de datos.

Prerrequisitos

Para seguir este tutorial, necesitarás:

Paso 1: Instalación de MySQL

En Ubuntu 22.04, puedes instalar MySQL usando el repositorio de paquetes APT. Al momento de escribir este artículo, la versión de MySQL disponible en el repositorio predeterminado de Ubuntu es la 8.0.28.

Para instalarlo, actualice el índice de paquetes en su servidor si no lo ha hecho recientemente:

sudo apt update

Luego instala el mysql-serverpaquete:

sudo apt install mysql-server

Asegúrese de que el servidor se esté ejecutando mediante el systemctl startcomando:

sudo systemctl start mysql.service

Estos comandos instalarán e iniciarán MySQL, pero no le solicitarán que establezca una contraseña ni realice ningún otro cambio de configuración. Dado que esto hace que su instalación de MySQL sea insegura, abordaremos este tema a continuación.

Paso 2: Configuración de MySQL

Para nuevas instalaciones de MySQL, deberá ejecutar el script de seguridad incluido en el sistema de gestión de bases de datos. Este script modifica algunas de las opciones predeterminadas menos seguras, como impedir el inicio de sesión remoto como root y eliminar usuarios de muestra.

Advertencia : A partir de julio de 2022, se producirá un error al ejecutar el mysql_secure_installationscript sin ninguna configuración adicional. Esto se debe a que este script intentará establecer una contraseña para la cuenta raíz de MySQL de la instalación, pero, por defecto en las instalaciones de Ubuntu, esta cuenta no está configurada para conectarse con contraseña.

Antes de julio de 2022, este script fallaba silenciosamente tras intentar establecer la contraseña de la cuenta raíz y continuar con el resto de las indicaciones. Sin embargo, al momento de escribir este artículo, el script devolverá el siguiente error después de ingresar y confirmar una contraseña:

Output ... Failed! Error: SET PASSWORD has no significance for user 'root'@'localhost' as the authentication method used doesn't store authentication data in the MySQL server. Please consider using ALTER USER instead if you want to change authentication parameters.

New password:

Esto llevará al script a un bucle recursivo del que sólo podrás salir cerrando la ventana de tu terminal.

Dado que el mysql_secure_installationscript realiza otras acciones útiles para mantener la seguridad de su instalación de MySQL, se recomienda ejecutarlo antes de empezar a usar MySQL para administrar sus datos. Sin embargo, para evitar este bucle recursivo, primero deberá ajustar la autenticación de su usuario root de MySQL.

Primero, abra el indicador de MySQL:

sudo mysql

A continuación, ejecute el siguiente ALTER USERcomando para cambiar el método de autenticación del usuario root a uno que utilice contraseña. El siguiente ejemplo cambia el método de autenticación a mysql_native_password:

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';

Después de realizar este cambio, salga del indicador de MySQL:

exit

Después de esto, puedes ejecutar el mysql_secure_installationscript sin problemas.

Ejecute el script de seguridad con sudo:

sudo mysql_secure_installation

Esto le guiará a través de una serie de indicaciones donde podrá realizar cambios en las opciones de seguridad de su instalación de MySQL. La primera le preguntará si desea configurar el complemento Validar contraseña, que permite comprobar la seguridad de las contraseñas de los nuevos usuarios de MySQL antes de considerarlas válidas.

Si elige configurar el complemento Validar contraseña, cualquier usuario de MySQL que cree que se autentique con una contraseña deberá tener una contraseña que cumpla con la política que seleccione:

OutputSecuring the MySQL server deployment.

Connecting to MySQL using a blank password.

VALIDATE PASSWORD COMPONENT can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD component?

Press y|Y for Yes, any other key for No: Y

There are three levels of password validation policy:

LOW    Length >= 8
MEDIUM Length >= 8, numeric, mixed case, and special characters
STRONG Length >= 8, numeric, mixed case, special characters and dictionary                  file

Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG:
 2

Independientemente de si decide configurar el complemento Validar contraseña, el siguiente paso será establecer una contraseña para el usuario root de MySQL . Ingrese y confirme una contraseña segura de su elección:

OutputPlease set the password for root here.


New password:

Re-enter new password:

Tenga en cuenta que aunque haya establecido una contraseña para el usuario root de MySQL, este usuario no está configurado actualmente para autenticarse con una contraseña al conectarse al shell de MySQL.

Si usaste el complemento Validar contraseña, recibirás información sobre la seguridad de tu nueva contraseña. El script te preguntará si deseas continuar con la contraseña que acabas de ingresar o si deseas ingresar una nueva. Si estás satisfecho con la seguridad de la contraseña que acabas de ingresar, presiona Enter Ypara continuar con el script:

OutputEstimated strength of the password: 100
Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : Y

Desde allí, puede presionar Yy luego ENTERaceptar los valores predeterminados para todas las preguntas subsiguientes. Esto eliminará algunos usuarios anónimos y la base de datos de prueba, deshabilitará los inicios de sesión remotos como root y cargará estas nuevas reglas para que MySQL respete inmediatamente los cambios realizados.

Nota: Una vez completado el script de seguridad, puede volver a abrir MySQL y cambiar el método de autenticación del usuario root al predeterminado. auth_socketPara autenticarse como usuario root de MySQL con una contraseña, ejecute este comando:

mysql -u root -p

Luego vuelva a utilizar el método de autenticación predeterminado usando este comando:

ALTER USER 'root'@'localhost' IDENTIFIED WITH auth_socket;

Esto significará que podrás volver a conectarte a MySQL como tu usuario root usando el sudo mysqlcomando.

Una vez completado el script, su instalación de MySQL estará protegida. Ahora puede crear un usuario de base de datos dedicado con el cliente MySQL.

Paso 3: Creación de un usuario MySQL dedicado y concesión de privilegios

Tras la instalación, MySQL crea una cuenta de usuario root que puede usar para administrar su base de datos. Este usuario tiene privilegios completos sobre el servidor MySQL, lo que significa que tiene control total sobre cada base de datos, tabla, usuario, etc. Por ello, se recomienda evitar usar esta cuenta fuera de las funciones administrativas. Este paso describe cómo usar el usuario root de MySQL para crear una nueva cuenta de usuario y otorgarle privilegios.

En sistemas Ubuntu con MySQL 5.7 (y versiones posteriores), el usuario root de MySQL se autentica mediante el auth_socketcomplemento por defecto, en lugar de una contraseña. Este complemento requiere que el nombre del usuario del sistema operativo que invoca el cliente MySQL coincida con el nombre del usuario MySQL especificado en el comando, por lo que debe invocarlo mysqlcon sudoprivilegios para acceder al usuario root de MySQL:

sudo mysql

Nota: Si instaló MySQL con otro tutorial y habilitó la autenticación con contraseña para root , deberá usar un comando diferente para acceder al shell de MySQL. El siguiente comando ejecutará su cliente MySQL con privilegios de usuario normales, y solo obtendrá privilegios de administrador en la base de datos al autenticarse:

mysql -u root -p

Una vez que tenga acceso al prompt de MySQL, puede crear un nuevo usuario con una CREATE USERinstrucción. Estas instrucciones siguen la siguiente sintaxis general:

CREATE USER 'username'@'host' IDENTIFIED WITH authentication_plugin BY 'password';

Después de CREATE USER, se especifica un nombre de usuario. A esto le sigue inmediatamente un @signo y el nombre de host desde el que se conectará este usuario. Si solo planea acceder a este usuario localmente desde su servidor Ubuntu, puede especificar localhost. No siempre es necesario escribir el nombre de usuario y el host entre comillas simples, pero esto puede ayudar a prevenir errores.

Tiene varias opciones para elegir el plugin de autenticación de usuario. El auth_socketplugin mencionado anteriormente puede ser práctico, ya que proporciona una seguridad sólida sin requerir que los usuarios válidos introduzcan una contraseña para acceder a la base de datos. Sin embargo, también impide las conexiones remotas, lo que puede complicar la interacción de programas externos con MySQL.

Como alternativa, puede omitir por completo esta parte de la sintaxis para que el usuario se autentique con el complemento predeterminado de MySQL. La documentación de MySQL recomienda este complemento para usuarios que desean iniciar sesión con contraseña debido a sus sólidas funciones de seguridad.WITH authentication_plugincaching_sha2_password

Ejecute el siguiente comando para crear un usuario que se autentique con [ nombre de usuario caching_sha2_password]. Asegúrese de usar sammysu nombre de usuario preferido y passworduna contraseña segura de su elección:

CREATE USER 'sammy'@'localhost' IDENTIFIED BY 'password';

Nota : Existe un problema conocido con algunas versiones de PHP que causa problemas con caching_sha2_password. Si planea usar esta base de datos con una aplicación PHP (por ejemplo, phpMyAdmin), le recomendamos crear un usuario que se autentique con el complemento anterior, aunque aún seguro mysql_native_password:

CREATE USER 'sammy'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';

Si no está seguro, siempre puede crear un usuario que se autentique con caching_sha2_pluginy luego ALTERmás tarde con este comando:

ALTER USER 'sammy'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';

Tras crear el nuevo usuario, puede otorgarle los privilegios correspondientes. La sintaxis general para otorgar privilegios de usuario es la siguiente:

GRANT PRIVILEGE ON database.table TO 'username'@'host';

El valor en esta sintaxis de ejemplo define las acciones que el usuario puede realizar en el `and` especificado . Puede otorgar varios privilegios al mismo usuario en un solo comando separándolos con una coma. También puede otorgar privilegios globales a un usuario introduciendo asteriscos ( ) PRIVILEGEen lugar de los nombres de las bases de datos y las tablas. En SQL, los asteriscos son caracteres especiales que se utilizan para representar “todas” las bases de datos o tablas.databasetable*

A modo de ejemplo, el siguiente comando otorga a un usuario privilegios globales sobre CREATE, ALTER, y DROPbases de datos, tablas y usuarios, así como la capacidad de acceder a INSERT, UPDATEy DELETEdatos de cualquier tabla del servidor. También le otorga la capacidad de consultar datos con SELECT, crear claves foráneas con la REFERENCESpalabra clave y realizar FLUSHoperaciones con el RELOADprivilegio . Sin embargo, solo debe otorgar a los usuarios los permisos que necesiten, así que puede ajustar los privilegios de sus usuarios según sea necesario.

Puede encontrar la lista completa de privilegios disponibles en la documentación oficial de MySQL .

Ejecute esta GRANTdeclaración, reemplazándola sammycon el nombre de su propio usuario MySQL, para otorgarle estos privilegios a su usuario:

GRANT CREATE, ALTER, DROP, INSERT, UPDATE, INDEX, DELETE, SELECT, REFERENCES, RELOAD on *.* TO 'sammy'@'localhost' WITH GRANT OPTION;

Tenga en cuenta que esta declaración también incluye WITH GRANT OPTION. Esto permitirá que su usuario de MySQL otorgue los permisos que tenga a otros usuarios del sistema.

Advertencia : algunos usuarios pueden querer otorgarle a su usuario MySQL el ALL PRIVILEGESprivilegio que les proporcionará amplios privilegios de superusuario similares a los privilegios del usuario root , de la siguiente manera:

GRANT ALL PRIVILEGES ON *.* TO 'sammy'@'localhost' WITH GRANT OPTION;

No se deben conceder privilegios tan amplios , ya que cualquiera con acceso a este usuario MySQL tendrá control total sobre todas las bases de datos del servidor.

A continuación, se recomienda ejecutar el FLUSH PRIVILEGEScomando. Esto liberará la memoria almacenada en caché por el servidor como resultado de las CREATE USERinstrucciones anteriores GRANT:

FLUSH PRIVILEGES;

Luego puedes salir del cliente MySQL:

exit

En el futuro, para iniciar sesión como su nuevo usuario MySQL, deberá utilizar un comando como el siguiente:

mysql -u sammy -p

La -pbandera hará que el cliente MySQL le solicite la contraseña de su usuario MySQL para poder autenticarse.

Por último, probemos la instalación de MySQL.

Paso 4: Prueba de MySQL

Independientemente de cómo lo hayas instalado, MySQL debería haberse iniciado automáticamente. Para comprobarlo, comprueba su estado.

systemctl status mysql.service

La salida será similar a la siguiente:

Output● mysql.service - MySQL Community Server
     Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2022-04-11 16:04:39 UTC; 2h 36min ago
    Process: 2593 ExecStartPre=/usr/share/mysql/mysql-systemd-start pre (code=exited, status=0/SUCCESS)
   Main PID: 2601 (mysqld)
     Status: "Server is operational"
      Tasks: 38 (limit: 1119)
     Memory: 354.3M
        CPU: 19.944s
     CGroup: /system.slice/mysql.service
             └─2601 /usr/sbin/mysqld

Si MySQL no se está ejecutando, puedes iniciarlo con sudo systemctl start mysql.

Para una comprobación adicional, puede intentar conectarse a la base de datos mediante la mysqladminherramienta, que es un cliente que permite ejecutar comandos administrativos. Por ejemplo, este comando indica que debe conectarse con el usuario MySQL llamado sammy ( ), solicitar una contraseña ( ) y devolver la versión. Asegúrese de cambiar el nombre de su usuario MySQL dedicado e introducir su contraseña cuando se le solicite:-u sammy-psammy

sudo mysqladmin -p -u sammy version

A continuación se muestra un ejemplo de la salida:

Outputmysqladmin  Ver 8.0.28-0ubuntu4 for Linux on x86_64 ((Ubuntu))
Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Server version          8.0.28-0ubuntu4
Protocol version        10
Connection              Localhost via UNIX socket
UNIX socket             /var/run/mysqld/mysqld.sock
Uptime:                 2 hours 31 min 57 sec

Threads: 2  Questions: 25  Slow queries: 0  Opens: 160  Flush tables: 3  Open tables: 79  Queries per second avg: 0.000

Esto significa que MySQL está en funcionamiento.

Conclusión

Ya tiene una configuración básica de MySQL instalada en su servidor. Aquí tiene algunos ejemplos de los pasos a seguir:

  • Configurar una pila LAMP o una pila LEMP
  • Practique la ejecución de consultas con SQL
  • Administre su instalación de MySQL con phpMyAdmin

Stephen Dove
Comments

April 27, 2025

Introducción a la terminología, interfaces y protocolos de redes

Introducción

Comprender las redes es fundamental para cualquier persona que administre un servidor. No solo es esencial para que sus servicios estén en línea y funcionen sin problemas, sino que también le proporciona la información necesaria para diagnosticar problemas.

Este artículo ofrece una descripción general de algunos conceptos comunes de redes. Analizaremos la terminología, los protocolos comunes y las responsabilidades y características de las diferentes capas de red.

Esta guía es independiente del sistema operativo, pero debería ser muy útil al implementar funciones y servicios que utilizan redes en su servidor.

Glosario de redes

Primero, definiremos algunos términos comunes que verá a lo largo de esta guía y en otras guías y documentación sobre redes.

Estos términos se ampliarán en las secciones correspondientes que siguen:

  • Conexión : En redes, una conexión se refiere a la información relacionada que se transfiere a través de una red. Generalmente, una conexión se establece antes de la transferencia de datos (siguiendo los procedimientos establecidos en un protocolo) y puede desestructurarse al final de la transferencia.
  • Paquete : Un paquete es la unidad más pequeña que se transfiere intencionalmente a través de una red. Al comunicarse a través de una red, los paquetes son los sobres que transportan los datos (en fragmentos) de un extremo a otro.

Los paquetes tienen una sección de encabezado que contiene información sobre el paquete, incluyendo el origen y el destino, las marcas de tiempo, los saltos de red, etc. La sección principal del paquete contiene los datos que se transfieren. A veces se denomina cuerpo o carga útil.

  • Interfaz de red : Una interfaz de red puede referirse a cualquier tipo de interfaz de software con hardware de red. Por ejemplo, si tiene dos tarjetas de red en su computadora, puede controlar y configurar cada interfaz de red asociada a ellas individualmente.

Una interfaz de red puede estar asociada a un dispositivo físico o ser la representación de una interfaz virtual. El dispositivo de bucle invertido, una interfaz virtual disponible en la mayoría de los entornos Linux para conectarse a la misma máquina, es un ejemplo de ello.

  • LAN : LAN significa «red de área local». Se refiere a una red o a una parte de ella que no es accesible públicamente a internet. Una red doméstica o de oficina es un ejemplo de LAN.
  • WAN : WAN significa “red de área extensa”. Se refiere a una red mucho más extensa que una LAN. Si bien WAN es el término relevante para describir redes grandes y dispersas en general, generalmente se refiere a Internet en su conjunto.

Si se dice que una interfaz está conectada a la WAN, generalmente se supone que es accesible a través de Internet.

  • Protocolo : Un protocolo es un conjunto de reglas y estándares que definen un lenguaje que los dispositivos pueden usar para comunicarse. Existe una gran cantidad de protocolos ampliamente utilizados en redes, y a menudo se implementan en diferentes capas.

Algunos protocolos de bajo nivel son TCP, UDP, IP e ICMP. Algunos ejemplos conocidos de protocolos de capa de aplicación, basados ​​en estos protocolos de bajo nivel, son HTTP (para acceder a contenido web), SSH y TLS/SSL.

  • Puerto : Un puerto es una dirección en una sola máquina que puede vincularse a un programa específico. No es una interfaz ni una ubicación física, pero permite que su servidor se comunique mediante más de una aplicación.
  • Cortafuegos : Un cortafuegos es un programa que decide si se debe permitir el tráfico entrante o saliente de un servidor. Un cortafuegos suele funcionar creando reglas que determinan qué tipo de tráfico es aceptable en qué puertos. Generalmente, los cortafuegos bloquean los puertos que no utiliza una aplicación específica en un servidor.
  • NAT : NAT significa Traducción de Direcciones de Red. Es una forma de reempaquetar y enviar las solicitudes entrantes a un servidor de enrutamiento a los dispositivos o servidores correspondientes en una LAN. Esto se suele implementar en redes LAN físicas para enrutar las solicitudes a través de una dirección IP a los servidores backend necesarios.
  • VPN : VPN significa red privada virtual. Es un medio para conectar redes LAN independientes a través de internet, manteniendo la privacidad. Se utiliza para conectar sistemas remotos como si estuvieran en una red local, a menudo por razones de seguridad.

Encontrará muchos otros términos, y esta lista no es exhaustiva. Explicaremos otros términos según sea necesario. En este punto, debería comprender algunos conceptos generales que nos permitirán abordar mejor los temas que se tratarán a continuación.

Capas de red

Si bien las redes suelen analizarse en términos de topología de manera horizontal, entre hosts su implementación se realiza en capas de manera vertical dentro de cualquier computadora o red determinada.

Esto significa que existen múltiples tecnologías y protocolos que se complementan para que la comunicación funcione. Cada capa superior abstrae un poco más los datos sin procesar.

También le permite aprovechar las capas inferiores de nuevas maneras sin tener que invertir tiempo y energía para desarrollar los protocolos y aplicaciones que manejan esos tipos de tráfico.

El lenguaje que usamos para describir cada esquema de capas varía significativamente según el modelo utilizado. Independientemente del modelo utilizado para describir las capas, la ruta de los datos es la misma.

A medida que los datos se envían desde una máquina, comienzan en la parte superior de la pila y se filtran hacia abajo. En el nivel más bajo, se produce la transmisión real a otra máquina. En este punto, los datos vuelven a ascender a través de las capas de la otra computadora.

Cada capa tiene la capacidad de agregar su propio “envoltorio” alrededor de los datos que recibe de la capa adyacente, lo que ayudará a las capas que vienen después a decidir qué hacer con los datos cuando se entregan.

Modelo TCP/IP

El modelo TCP/IP, más conocido como el conjunto de protocolos de Internet, es un modelo de capas ampliamente adoptado. Define cuatro capas independientes:

  • Aplicación : En este modelo, la capa de aplicación se encarga de crear y transmitir datos de usuario entre aplicaciones. Las aplicaciones pueden estar en sistemas remotos y deben funcionar como si estuvieran localmente para el usuario final. Se dice que esta comunicación se realiza entre pares .
  • Transporte : La capa de transporte es responsable de la comunicación entre procesos. Este nivel de red utiliza puertos para gestionar diferentes servicios.
  • Internet : La capa de Internet se utiliza para transportar datos entre nodos de una red. Esta capa conoce los puntos finales de las conexiones, pero no se ocupa de la conexión real necesaria para llegar de un lugar a otro. Las direcciones IP se definen en esta capa como una forma de acceder a sistemas remotos de forma direccionable.
  • Enlace : La capa de enlace implementa la topología de la red local, lo que permite que la capa de Internet presente una interfaz direccionable. Establece conexiones entre nodos vecinos para el envío de datos.

Como puede ver, el modelo TCP/IP es abstracto y fluido. Esto popularizó su implementación y le permitió convertirse en la forma dominante de categorizar las capas de red.

Interfaces

Las interfaces son puntos de comunicación de red para su computadora. Cada interfaz está asociada a un dispositivo de red físico o virtual.

Normalmente, su servidor tendrá una interfaz de red configurable para cada tarjeta de Internet Ethernet o inalámbrica que tenga.

Además, definirá una interfaz de red virtual denominada “loopback” o interfaz localhost. Esta se utiliza para conectar aplicaciones y procesos de un mismo ordenador con otros. En muchas herramientas, se denomina “lo”.

Muchas veces, los administradores configuran una interfaz para atender el tráfico a Internet y otra interfaz para una LAN o red privada.

En centros de datos con redes privadas habilitadas (incluidos los Droplets de DigitalOcean), su VPS tendrá dos interfaces de red. La interfaz “eth0” se configurará para gestionar el tráfico de internet, mientras que la interfaz “eth1” se comunicará con una red privada.

Protocolos

Las redes funcionan mediante la superposición de varios protocolos diferentes. De esta forma, un mismo dato puede transmitirse utilizando múltiples protocolos encapsulados entre sí.

Comenzaremos con protocolos implementados en las capas de red inferiores y avanzaremos hasta llegar a protocolos con mayor abstracción.

Control de acceso al medio

El control de acceso al medio es un protocolo de comunicaciones que se utiliza para distinguir dispositivos específicos. Cada dispositivo debe recibir una dirección MAC (dirección de control de acceso al medio ) única y codificada durante su fabricación, lo que lo diferencia de cualquier otro dispositivo en internet.

Direccionar el hardware mediante la dirección MAC le permite hacer referencia a un dispositivo mediante un valor único incluso cuando el software superior puede cambiar el nombre de ese dispositivo específico durante la operación.

El direccionamiento MAC es uno de los únicos protocolos de la capa de enlace de bajo nivel con el que probablemente interactuará de manera regular.

Propiedad intelectual

El protocolo IP es uno de los protocolos fundamentales que permiten el funcionamiento de internet. Las direcciones IP son únicas en cada red y permiten que las máquinas se direccionen entre sí a través de ella. Se implementa en la capa de internet del modelo TCP/IP.

Las redes pueden conectarse entre sí, pero el tráfico debe enrutarse al cruzar los límites de la red. Este protocolo asume una red poco fiable y múltiples rutas hacia el mismo destino, entre las que puede cambiar dinámicamente.

Existen diversas implementaciones del protocolo. La implementación más común actualmente son las direcciones IPv4, que siguen el patrón [número] 123.123.123.123, aunque las direcciones IPv6, que también siguen el patrón [número] 2001:0db8:0000:0000:0000:ff00:0042:8329, están ganando popularidad debido a la cantidad limitada de direcciones IPv4 disponibles.

ICMP

ICMP significa Protocolo de Mensajes de Control de Internet. Se utiliza para enviar mensajes entre dispositivos para indicar su disponibilidad o errores. Estos paquetes se utilizan en diversas herramientas de diagnóstico de red, como pingy traceroute.

Normalmente, los paquetes ICMP se transmiten cuando un tipo de paquete diferente detecta un problema. Se utilizan como mecanismo de retroalimentación para las comunicaciones de red.

TCP

TCP significa protocolo de control de transmisión. Se implementa en la capa de transporte del modelo TCP/IP y se utiliza para establecer conexiones fiables.

TCP es uno de los protocolos que encapsula datos en paquetes. Luego, los transfiere al extremo remoto de la conexión mediante los métodos disponibles en las capas inferiores. En el otro extremo, puede comprobar si hay errores, solicitar el reenvío de ciertos fragmentos y reensamblar la información en un único fragmento lógico para enviarlo a la capa de aplicación.

El protocolo establece una conexión antes de la transferencia de datos mediante un sistema denominado protocolo de enlace de tres vías. Este protocolo permite que ambos extremos de la comunicación reconozcan la solicitud y acuerden un método para garantizar la fiabilidad de los datos.

Una vez enviados los datos, la conexión se interrumpe mediante un protocolo de enlace de cuatro vías similar.

TCP es el protocolo elegido para muchos de los usos más populares de Internet, incluidos WWW, SSH y el correo electrónico.

UDP

UDP significa protocolo de datagramas de usuario. Es un protocolo complementario popular de TCP y también se implementa en la capa de transporte.

La diferencia fundamental entre UDP y TCP es que UDP ofrece una transferencia de datos poco fiable. No verifica la recepción de datos en el otro extremo de la conexión. Esto podría parecer perjudicial, y para muchos propósitos lo es. Sin embargo, también es fundamental para ciertas funciones.

Dado que no es necesario esperar la confirmación de la recepción de los datos ni forzar su reenvío, UDP es mucho más rápido que TCP. No establece una conexión con el host remoto, simplemente envía datos sin confirmación.

Al ser una transacción directa, resulta útil para comunicaciones como la consulta de recursos de red. Además, no mantiene un estado, lo que la hace ideal para transmitir datos desde una máquina a varios clientes en tiempo real. Esto la hace ideal para VoIP, juegos y otras aplicaciones que no admiten retrasos.

HTTP

HTTP significa protocolo de transferencia de hipertexto. Es un protocolo definido en la capa de aplicación que constituye la base de la comunicación en la web.

HTTP define varios verbos que indican al sistema remoto qué se solicita. Por ejemplo, GET, POST y DELETE interactúan con los datos solicitados de forma diferente. Para ver un ejemplo de las diferentes solicitudes HTTP en acción, consulte Cómo definir rutas y métodos de solicitud HTTP en Express .

DNS

DNS significa sistema de nombres de dominio. Es un protocolo de capa de aplicación que proporciona un mecanismo de nombres intuitivo para los recursos de internet. Es lo que vincula un nombre de dominio a una dirección IP y permite acceder a sitios web por su nombre en el navegador.

SSH

SSH significa Secure Shell. Es un protocolo cifrado implementado en la capa de aplicación que permite comunicarse con un servidor remoto de forma segura. Muchas tecnologías adicionales se basan en este protocolo gracias a su cifrado de extremo a extremo y su ubicuidad.

Hay muchos otros protocolos que no hemos cubierto y que son igualmente importantes. Sin embargo, esto debería brindarle una buena visión general de algunas de las tecnologías fundamentales que hacen posible internet y las redes.

Conclusión

En este punto, debería estar familiarizado con la terminología de redes y comprender cómo se comunican los diferentes componentes. Esto le ayudará a comprender otros artículos y la documentación de su sistema.

A continuación, para ver un ejemplo de alto nivel del mundo de la lectura, puede leer Cómo realizar solicitudes HTTP en Go .

Stephen Dove
Comments

April 27, 2025

Cómo usar Vim para la edición avanzada de texto plano o código en un VPS

Introducción


Vim, una mejora del vieditor de texto clásico, es extremadamente potente para editar código y texto plano. Aunque al principio pueda parecer obtuso y difícil, es una de las formas más eficientes de editar texto gracias a su sintaxis de comandos similar a la del lenguaje.

En un artículo anterior, explicamos cómo instalar Vim y realizar ediciones básicas . En este documento, abordaremos temas más avanzados que pueden ayudar a demostrar la versatilidad de la edición.

Asumiremos que ha instalado vim y está familiarizado con los comandos básicos de movimiento y edición analizados en el artículo vinculado anteriormente.

Navegación avanzada


Antes de comenzar con nuevo material, repasemos un poco la navegación que aprendimos en el artículo anterior:

  • Movimientos básicos
    • h: izquierda
    • l: derecha
    • j: abajo
    • k: arriba
  • Otros movimientos
    • gg: parte superior del documento
    • G: parte inferior del documento o número de línea si se coloca un número delante de G
    • w: siguiente palabra
    • e: fin de palabra
    • 0: comienzo de línea
    • $: fin de línea

Como pueden ver, ya tenemos bastantes comandos de movimiento a nuestra disposición. Sin embargo, también podemos dirigir el movimiento de otras maneras.

Podemos mover el cursor a diferentes áreas en la porción actualmente visible de la página usando estos comandos:

  • H : Mueve el cursor a la parte superior de la página visible actualmente (piensa en “alto”)
  • M : Mueve el cursor al centro de la página visible actualmente
  • L : Mueve el cursor a la parte inferior de la página visible actualmente (piensa en “abajo”)

Si queremos mover la página en lugar del cursor (como en el desplazamiento), podemos utilizar estos comandos:

  • CTRL-D : Av Pág
  • CTRL-U : Re Pág
  • CTRL-E : desplazarse hacia abajo una línea
  • CTRL-Y : desplazarse hacia arriba una línea

También podemos navegar por bloques lógicos de información. Esto puede ser útil si se escribe texto normal en lugar de código. Son similares a los comandos de navegación por palabras y líneas.

  • ) : Mover al inicio de la siguiente oración
  • ( : Mover al inicio de la última oración
  • } : Mover al inicio del siguiente párrafo (delimitado por una línea en blanco)
  • { : Mover al inicio del último párrafo (delimitado por una línea en blanco)

También puedes definir tus propios puntos en el archivo para saltar a ellos. Puedes establecerlos marksen cualquier punto del archivo. Luego, puedes referenciar esas marcas para saltar a ese punto o pasarlo a un comando que acepte movimientos:

  • m : Escribir “m” seguido de una letra crea una marca de referencia con esa letra.
    • Las letras minúsculas son específicas del documento actual, mientras que las letras mayúsculas solo se pueden usar una vez (se pueden usar para saltar a secciones en diferentes documentos).
  • : La comilla simple seguida de una letra de marca (previamente definida con la “m” como arriba), moverá el cursor al comienzo de la línea que contiene esa marca.
  • ` : La comilla invertida seguida de una letra de marca moverá el cursor a la posición exacta de la marca.

Estos comandos permiten colocar una marca y luego retirar, eliminar o formatear el área definida entre la posición actual y la marca. Esto permite un control muy preciso de las opciones de edición.

Cómo gestionar documentos


A menudo, al trabajar, ya sea en un proyecto de software o en un trabajo académico, es necesario poder referenciar varios documentos a la vez. Vim ofrece diferentes maneras de hacerlo, según cómo se desee trabajar.

Cómo gestionar los buffers


Una forma de gestionar varios archivos es mediante buffers. Los búferes suelen representar un archivo abierto para edición. Son básicamente todo lo que vim tiene abierto actualmente y a lo que puede acceder fácilmente.

Abrimos varios archivos con vim de la siguiente manera:

vim file1 file2 file3

Cada uno de estos archivos se abre en su propio buffer. Actualmente, solo podemos ver el primer archivo.

Podemos ver qué buffers tenemos disponibles escribiendo :buffers.

:buffers

:buffers
  1 %a  "file1"             line 1
  2     "file2"             line 0
  3     "file3"             line 0
Press ENTER or type command to continue

Si deseamos consultar el siguiente búfer, podemos escribir :bn. Esto cambiará al siguiente búfer. De igual forma, podemos cambiar a un búfer por número (en la primera columna de arriba) o por nombre, escribiendo b. Esto funciona incluso si el nombre del archivo está incompleto.

A continuación se muestran algunos de los comandos para administrar buffers:

  • :buffers : Lista de buffers disponibles
  • :ls : Lo mismo que arriba
  • :bn : Cambiar al siguiente búfer
  • :bp : Cambiar al búfer anterior
  • :bfirst : Cambiar al primer búfer
  • :blast : Cambiar al último búfer
  • :bdelete : Elimina el búfer actual
  • :badd : Abre un nuevo buffer con el nombre de archivo que sigue
  • :e : Edita otro archivo en un nuevo buffer y cámbialo.

Cómo administrar Windows


Un mecanismo de control independiente que Vim ofrece para gestionar múltiples archivos es el concepto de windowso views. Esto permite dividir el área de edición actual en diferentes ventanas para poder ver varios búferes simultáneamente.

Para dividir el espacio de trabajo actual en ventanas independientes, puede escribir :splito :sp. Esto abre una nueva ventana sobre la actual y la enfoca. Puede cambiar el búfer que se muestra en la nueva ventana usando los comandos de búfer mostrados arriba.

Aquí hay algunos comandos que podemos usar para crear y administrar ventanas:

  • :sp : Divide la ventana actual en dos. Inicialmente, se mostrará el mismo búfer en cada ventana.
    • Anteponga un número a la “sp” para establecer la nueva altura de la ventana.
  • :vs : Divide la ventana actual verticalmente. Inicialmente, se mostrará el mismo búfer en cada ventana.
    • Anteponga un número al “vs” para establecer el nuevo ancho de la ventana.
  • CTRL-ww : Cambiar el foco a la siguiente ventana
  • CTRL-w(movimiento) : Cambia el foco a la ventana en la dirección (h,j,k,l) ​​indicada
  • CTRL-wc : Cerrar la ventana actual
  • CTRL-w+ : Aumentar el tamaño de la ventana actual
  • CTRL-w- : Disminuir el tamaño de la ventana actual
  • CTRL-w= : Establecer todas las ventanas con el mismo tamaño
  • #CTRL-w_ : Establece la altura al tamaño indicado por el “#” precedente
  • :only : Cierra todas las ventanas excepto la actual
  • CTRL-wn : Abre una nueva ventana con un nuevo búfer

Cómo administrar pestañas


Un tercer concepto para gestionar múltiples documentos en Vim es el de tabs. A diferencia de muchos programas, en Vim, las pestañas pueden contener ventanas, no al revés. Las pestañas pueden contener ventanas, que actúan como ventanas gráficas en los búferes.

Podemos gestionar el diseño de la ventana de cada pestaña por separado. Para crear pestañas, podemos usar el :tabnewcomando para abrir una nueva pestaña.

Algunas formas sencillas de administrar las pestañas son:

  • :tabnew : Abrir nueva pestaña
  • :tabclose : Cerrar la pestaña actual
  • :tabn : Cambiar a la siguiente pestaña
  • gt : Cambiar a la siguiente pestaña
  • :tabp : Cambiar a la pestaña anterior
  • gT : Cambiar a la pestaña anterior
  • :tab ball : Abre todos los buffers en pestañas individuales
  • :tabs : Lista todas las pestañas disponibles

Al cambiar entre búferes, ventanas y pestañas, a veces resulta confuso saber qué archivo estás viendo. Una forma rápida de averiguar el nombre del archivo es escribir:

  • CTRL-g : Muestra el nombre del archivo actual

Comandos específicos del documento


Dependiendo del tipo de documentos con los que esté tratando, vim tiene ciertas funcionalidades que pueden ayudarlo.

Texto sin formato


Si edita documentos de texto sin formato, Vim puede ayudarle de diversas maneras. Una de las funciones esenciales para esta función es el corrector ortográfico.

Para activar la corrección ortográfica en vim, puedes escribir:

:set spell

Para configurar el idioma que se está utilizando, puede escribir:

:set spelllang=[language abbreviation]

Ahora, se revisará la ortografía de su documento. La línea ondulada normal aparecerá debajo de las palabras mal escritas. Así es como se usa.

Para saltar hacia adelante y hacia atrás entre palabras mal escritas, escriba:

]s    # Jump to next mistake
[s    # Jump to previous mistake

Una vez que el cursor esté sobre una palabra mal escrita, podrá ver sugerencias ortográficas escribiendo:

z=

Esto le mostrará una lista de posibles coincidencias. Puede seleccionar la opción que desee eligiendo el número asociado o pulsar ENTER para dejar la palabra como está.

Si desea marcar una palabra como correcta , puede agregarla a una lista de ortografía. Vim mantiene dos listas de ortografía: una normal y una temporal que se usará en la sesión actual.

Para agregar la palabra a la lista de palabras “buenas”, utilice uno de estos comandos:

zg    # Adds word to regular dictionary
zG    # Adds word to the current session dictionary

Si agrega una palabra accidentalmente, puede eliminarla yendo a la palabra y escribiendo:

zug   # Remove word from regular dictionary
zuG   # Remove word from the current session dictionary

Si a menudo tiene que escribir palabras o frases largas, puede agregar una abreviatura.

Si escribimos :abseguido de una abreviatura y una expansión, vim ingresará la expansión siempre que escribamos la abreviatura seguida de un espacio.

Por ejemplo, si somos puristas y seguimos el ejemplo de Richard Stallman de corregir cualquier uso de “Linux” con “GNU/Linux”, podemos crear una abreviatura que lo haga automáticamente:

:ab Linux GNU/Linux

Ahora, cuando escribimos “Linux”, vim sustituirá automáticamente “GNU/Linux”.

Linux is an operating system.

Cambios en:

GNU/Linux is an operating system.

Sin embargo, si nos encontramos hablando específicamente del kernel, donde sólo la palabra Linux sería apropiada, podemos cancelar la expansión escribiendo CTRL-Vantes de escribir el espacio.

GNU/Linux is an operating system with Linux(CTRL-V) as a kernel.

Si ya no queremos utilizar esta abreviatura, podemos eliminarla con este comando:

:una Linux 

Ahora nuestro “Linux” seguirá siendo “Linux”.

Otra cosa que podrías tener que hacer de vez en cuando es insertar caracteres que no están en un teclado QWERTY tradicional. Los llamamos “dígrafos”. Puedes ver una lista de los dígrafos de Vim escribiendo:

:digraphs

NU ^@  10    SH ^A   1    SX ^B   2    EX ^C   3    ET ^D   4    EQ ^E   5
AK ^F   6    BL ^G   7    BS ^H   8    HT ^I   9    LF ^@  10    VT ^K  11
FF ^L  12    CR ^M  13    SO ^N  14    SI ^O  15    DL ^P  16    D1 ^Q  17
D2 ^R  18    D3 ^S  19    D4 ^T  20    NK ^U  21    SY ^V  22    EB ^W  23
CN ^X  24    EM ^Y  25    SB ^Z  26    EC ^[  27    FS ^\  28    GS ^]  29
RS ^^  30    US ^_  31    SP     32    Nb #   35    DO $   36    At @   64

Ahora, puedes insertar cualquiera de los caracteres en la columna derecha escribiendo CTRL-kseguido de las dos letras en la columna izquierda.

Por ejemplo, en mi computadora, para ingresar el signo de libra esterlina, puedo escribir esto cuando estoy en modo de inserción:

CTRL-k Pd

£

Código fuente


Si está codificando, hay varias cosas diferentes que lo ayudarán a interactuar con su código.

Una de las más básicas es el resaltado de sintaxis. Puedes activarlo escribiendo:

:syntax on

Esto debería configurar el resaltado de sintaxis para su archivo según la extensión detectada. Si desea cambiar el idioma del resaltado, puede hacerlo configurando el idioma con:

:set filetype=[language]

Si desea utilizar una utilidad del sistema para modificar algunas líneas de su archivo, puede llamarla usando el !comando en modo normal.

Este comando acepta un movimiento y luego lo envía al comando que le sigue.

![motion] filter

Por ejemplo, para ordenar las líneas desde la posición actual hasta el final del archivo, puede escribir:

!G sort

Sort es un comando de Linux que ordena la entrada, alfabéticamente de forma predeterminada.

Si queremos insertar la salida de un comando en el archivo, navegue hasta una línea en blanco donde desee la salida. Escriba:

!!command

Esto colocará la salida del comando especificado en el documento.

Si queremos ver el resultado de un comando, pero no deseamos insertarlo en el documento, también podemos utilizar la versión en modo comando (:), que sería:

:!command

Esto le mostrará los resultados del comando, pero regresará a su documento sin modificaciones cuando termine.

Reducir la repetición


A menudo, al editar o crear cualquier tipo de archivo, te encontrarás repitiendo muchas operaciones iguales o similares. Por suerte, vim ofrece algunas maneras de guardar grupos de comandos en macros.

Para comenzar a grabar una macro, puede escribir qseguido de una letra para hacer referencia a la macro.

qa    # will save macro "a"

Cualquier comando que escriba se grabará como parte de la macro. Para finalizar la macro, puede qvolver a escribir.

Entonces si escribimos:

qa0c3wDELETED<esc>q

Esto iniciaría una macro (guardada como “a”), iría al principio de la línea y reemplazaría las siguientes tres palabras con la palabra “DELETED”. Luego, saldría del modo de inserción y finalizaría la macro.

Para reproducir esta macro, comenzando en la posición actual del cursor, utilice el @carácter seguido de la referencia de la macro:

@a

Esto reproducirá los comandos macro comenzando en la posición actual.

Si queremos crear una macro que finalice en modo de inserción, debemos finalizarla de otra manera (al escribir “q”, simplemente se insertará una “q”). Podemos ejecutar un comando en modo normal en modo de inserción precediéndolo con “< CTRL-O.

Por lo tanto, si queremos cambiar el contenido de los primeros paréntesis de esta línea, podríamos tener una macro que diga:

qi0f(lct)<CTRL-O>q

Esto crea una macro “i”. La macro se desplaza al principio de la línea actual. Encuentra el paréntesis de apertura y se desplaza un carácter a la derecha (para moverse dentro del paréntesis). Después, cambia todo hasta el paréntesis de cierre. Con vim en modo de inserción esperando el texto de reemplazo, pulsamos CTRL-Oseguido de qpara finalizar la macro, quedando en modo de inserción listos para reemplazar el texto.

Conclusión


Ahora deberías tener una idea de algunas maneras más complejas en que vim puede ayudarte. Aunque esto pueda parecer mucho, es solo el comienzo.

Hay muchas funciones que no hemos mencionado, y no es necesario que las conozcas todas. Aprenderás lo importante según cómo uses vim. Cuanto más practiques y lo uses a diario, más natural te resultará y más potente será.

Stephen Dove