Linux

Cuanto mejora el desempeño aplicar técnicas de contenedorización (Docker, Swarm, Kubernetes)a aplicaciones frente a instalaciones unitarias de la misma?

La contenedorización de aplicaciones (modelo de arquitectura) puede ofrecer varias mejoras en términos de desempeño en comparación con las instalaciones unitarias de las mismas aplicaciones. Algunas de las mejoras potenciales incluyen:

  1. Mayor eficiencia en la utilización de recursos: Al usar contenedores, múltiples aplicaciones pueden ejecutarse en un mismo servidor físico, lo que permite una mejor utilización de los recursos y reduce la necesidad de tener múltiples servidores dedicados para cada aplicación.
  2. Mayor rapidez en la implementación y actualización de aplicaciones: Al tener las aplicaciones en contenedores, se pueden crear, implementar y actualizar rápidamente nuevas instancias de la aplicación. Esto puede ayudar a reducir el tiempo de inactividad y mejorar la eficiencia en general.
  3. Mayor portabilidad de aplicaciones: Los contenedores se pueden mover fácilmente de un servidor a otro, lo que facilita la migración de aplicaciones entre diferentes entornos y reduce el riesgo de incompatibilidades.
  4. Mayor seguridad: Los contenedores ofrecen un aislamiento de recursos más efectivo que las instalaciones unitarias, lo que puede mejorar la seguridad de las aplicaciones y reducir el riesgo de interferencia entre diferentes aplicaciones en un mismo servidor.

Sin embargo, es importante tener en cuenta que la contenedorización también puede requerir un mayor esfuerzo de configuración y mantenimiento, especialmente si se utilizan múltiples contenedores para una sola aplicación. Además, la contenedorización no siempre es adecuada para todas las aplicaciones, y puede haber casos en los que una instalación unitaria sigue siendo la mejor opción.

Existe alguna métrica o estádistica aplicable al uso de la contenedorización frente a instalaciones unitarias de aplicaciones?

Existen varias métricas y estadísticas que se pueden utilizar para evaluar el uso de la contenedorización en comparación con las instalaciones unitarias de aplicaciones. Algunas de las métricas más comunes incluyen:

  1. Tiempo de implementación: El tiempo que lleva implementar una aplicación en un entorno de contenedorización en comparación con una instalación unitaria.
  2. Utilización de recursos: La cantidad de recursos que se utilizan al ejecutar una aplicación en un entorno de contenedorización en comparación con una instalación unitaria.
  3. Escalabilidad: La capacidad del entorno de contenedorización para manejar aumentos en la carga de trabajo y la escalabilidad de la aplicación en comparación con una instalación unitaria.
  4. Tiempo de inactividad: La cantidad de tiempo que la aplicación está inactiva debido a problemas técnicos o de mantenimiento en un entorno de contenedorización en comparación con una instalación unitaria.
  5. Seguridad: El nivel de seguridad que ofrece un entorno de contenedorización en comparación con una instalación unitaria.
  6. Costo: El costo total de operar y mantener una aplicación en un entorno de contenedorización en comparación con una instalación unitaria.

Al evaluar el uso de la contenedorización frente a las instalaciones unitarias de aplicaciones, es importante considerar estas métricas y otras que puedan ser relevantes para su caso específico.

Docker y Swarm?

Docker y Docker Swarm son dos tecnologías muy útiles y populares para la contenedorización de aplicaciones. Aquí hay algunas consideraciones sobre estas tecnologías:

Docker: Docker es una plataforma de contenedorización de aplicaciones que permite a los desarrolladores crear, probar y distribuir aplicaciones en contenedores. Docker es conocido por ser fácil de usar y rápido en términos de tiempo de implementación. Además, la comunidad de Docker es muy activa y hay una gran cantidad de recursos y documentación disponibles para ayudar a los desarrolladores a trabajar con la plataforma.

Docker Swarm: Docker Swarm es una herramienta de orquestación de contenedores que se utiliza para administrar múltiples contenedores y nodos en un clúster de Docker. Swarm permite a los desarrolladores automatizar la implementación, el escalado y la administración de aplicaciones en contenedores en un entorno distribuido. Swarm se integra estrechamente con Docker, lo que lo convierte en una solución popular para administrar aplicaciones en contenedores.

En resumen, Docker y Docker Swarm son herramientas muy útiles y ampliamente utilizadas en la contenedorización de aplicaciones. Si está interesado en trabajar con contenedores, definitivamente vale la pena explorar estas tecnologías y aprender cómo pueden beneficiar a su entorno de desarrollo y despliegue.

Kubernetes

Kubernetes es considerado un excelente recurso para la orquestación de contenedores y es ampliamente utilizado en la industria de la tecnología. Kubernetes fue desarrollado originalmente por Google y ahora es un proyecto de código abierto mantenido por la Cloud Native Computing Foundation (CNCF).

Kubernetes es una plataforma de orquestación de contenedores que permite a los desarrolladores implementar, escalar y administrar aplicaciones en contenedores de manera eficiente y flexible. Con Kubernetes, los desarrolladores pueden automatizar el despliegue de aplicaciones, administrar el estado de los contenedores, distribuir el tráfico de red y actualizar aplicaciones sin tiempo de inactividad. Además, Kubernetes tiene una amplia gama de características y herramientas que lo hacen altamente escalable y adaptable a diferentes necesidades empresariales.

Kubernetes también cuenta con una gran comunidad de desarrolladores y usuarios, lo que ha llevado a la creación de muchos recursos y herramientas adicionales, como herramientas de monitoreo, administración de clústeres, análisis de registros y más. También hay muchas opciones de proveedores de servicios en la nube que ofrecen soluciones de Kubernetes gestionadas, lo que facilita aún más la implementación y administración de aplicaciones en contenedores.

En resumen, Kubernetes es una herramienta poderosa y altamente valorada en la orquestación de contenedores y se ha convertido en un estándar de facto en la industria de la tecnología para la administración de aplicaciones en contenedores a gran escala.

On Coursera: https://www.coursera.org/courses?query=kubernetes

Archivos de configuración en Python y conexión hacia MySQL, PostegreSQL y Oracle DB.

Los archivos de configuración tienen una amplia gama de aplicaciones utilizadas principalmente por los sistemas operativos para personalizar un entorno. Para los programadores o desarrolladores, la configuración de parámetros iniciales para el software sin codificar datos en el programa es uno de los casos de uso más frecuentes. Le permite modificar dicha configuración sin acceder al código fuente del programa.

En otras palabras, se le puede indicar al software que vaya a un archivo de configuración para obtener la información precisa que necesita para aquellas variables que pueden variar con el tiempo, como direcciones IP, nombres de host, nombres de usuario, contraseñas y nombres de bases de datos.

Escribir un archivo separado con código Python es la forma más sencilla de crear archivos de configuración. Puede darle un nombre como base de datosconfig.py. Luego, para evitar cargarlo involuntariamente, puede agregar la línea *<nombre de archivo> a su archivo .gitignore .

Formato del archivo de configuración

YAML, JSON, TOML e INI son los formatos populares y estandarizados de archivos de configuración.

La mayoría de los programas en python y bibliotecas aceptan fácilmente YAML e INI. INI tiene solo 1 nivel jerárquico, por lo que es la solución más simple. INI, por otro lado, no tiene tipos de datos; todo está codificado como una cadena.

Extensiones de archivos

Las extensiones de extensión dan al usuario y al sistema una pista sobre el contenido de un archivo. Los extremos razonables del archivo de configuración incluidos son:

  • La extensión config.py es para los archivos de Python.
  • La extensión .yaml / .yml es para si la configuración se realiza en formato YAML.
  • La extensión .json es para los archivos de configuración escritos en formato JSON.
  • El archivo de extensión .ini es un archivo particular que almacena datos de configuración en un formato sencillo y preestablecido.
  • .CFG o Varios programas utilizan un archivo de configuración con la extensión » CONFIG » para almacenar configuraciones exclusivas de su software. Mientras que algunos archivos de configuración se guardan como archivos de texto sin formato, otros pueden estar en un formato específico del programa.
  • Extensión ~/.[nombre de mi aplicación] En los sistemas Linux, la convención de nomenclatura para los archivos de configuración es «RC». RC es «común» y es un antiguo sistema informático.

Crear un archivo de configuración en Python

Configparser.py es un módulo de Python que simplifica la escritura, lectura y modificación de archivos .ini .

Para instalar este módulo, debe abrir su símbolo del sistema y escribir el comando dado:

pip install configparser

El objetivo principal de Configureparser es leer y escribir archivos .ini, aunque también acepta diccionarios y objetos de archivos iterables como entradas. Cada archivo .ini se divide en partes que incluyen varios pares clave-valor.

Analicemos cómo crear un archivo de configuración en Python. Siguiendo los pasos que se indican a continuación, podemos crear un archivo de configuración:

  • Primero, importe el módulo configparser.
  • Cree un objeto de configparser.ConfigParser() guárdelo en una variable.
  • Cree secciones según las necesidades utilizando el método .add_section(«section_name»).
  • Agregue pares clave-valor a la sección, usando el método .set(«sección»,»clave»,»valor»).
  • Para guardar la configuración:
    con abrir (ruta/»nombre_de_archivo.ini», «w») como nombre de archivo:
    config object.write(fileName)

Comprendamos cómo crear un archivo de configuración en Python tomando un ejemplo a continuación:

# Code goes from here
# importing config parser
import configparser


# creating object of configparser
config = config parser.ConfigParser()


# creating a section
config.add_section("database")


# adding key-value pairs
config.set("database", "host", "local host")
config.set("database", "admin", "local admin")
config.set("database", "password", "qwerty@123")
config.set("database", "port no", "2253")
config.set("database", "database", "SQL")
config.set("database", "version", "1.1.0")


# creating another section
config.add_section("user")


# adding key-value pairs
config.set("user", "name", "test_name")
config.set("user", "e-mail", "test@example.com")
config.set("user", "id", "4759422")




with open("database.ini", 'w') as example:
   config.write(example)

En el ejemplo anterior, para crear un archivo de configuración INI, necesitamos importar configparser.

Primero, hemos creado un objeto de analizador de configuración utilizando el método config parser.ConfigParser(). Para hacer secciones en el archivo INI, usamos el método .add_section («nombre de la sección»).

Para completar los valores en la sección tenemos el método .set(). Se necesitan 3 parámetros: el primero es el nombre de la sección, el segundo es el nombre de la clave o la opción y el tercero es el valor.

Después de archivar secciones, necesitamos crear un archivo de .ini. Para crear un archivo, usamos “with open()(). En estos corchetes, damos el nombre del archivo para que cree un archivo en el mismo directorio. Para escribir valor, usaremos el método .write().

Salidas del archivo database.ini

Leer el archivo de configuración

Hemos aprendido cómo construir y actualizar el archivo de configuración en Python. Ahora que se ha creado, en nuestra clase principal, leamos los valores del archivo de configuración. La parte más fácil y clara viene a continuación.

Cada configuración se mantiene como una cadena porque Configureparser no intenta adivinar los tipos de datos en el archivo de configuración. Sin embargo, ofrece algunas formas de cambiar el tipo de datos de una cadena al apropiado. El tipo más interesante es el booleano, ya que puede distinguir entre valores booleanos como «sí» y «no», «encendido» y «apagado», «verdadero» y «falso», y «1» y «0».

También podría leer desde un objeto de archivo iterable, un diccionario o una cadena usando read_dict(), read_string() o read_file ().

Comprendamos cómo leer archivos de configuración en Python tomando un ejemplo dado

abajo:

# Code goes from here
# importing config parser
import configparser

# creating the object of configparser
config_data = configparser.ConfigParser()

# reading data
config_data.read("database.ini")

# app configuration data
database = config_data["database"]

# admin data
user = config_data["user"]

print("database data")
for database_data in database:
   print(f"{database_data} = {database.get(database_data)}")

print("\nuser data")
for user_data in user:
   print(f"{user_data} = {user.get(user_data)}")
Salida de la lectura del archivo de configuración

En el ejemplo anterior, tenemos un archivo de configuración » example.ini «. Intentemos leerlo. Para leer un archivo INI, necesitamos importar el módulo configparser.py. Ahora creamos un objeto de analizador de configuración usando el método config parser.ConfigParser() . En este momento, este objeto no tiene ningún dato. Podemos leer un archivo externo usando .read.

Tenemos 2 secciones en el archivo ini. Una es la sección de la base de datos y otra es la sección del usuario. Almacenemos estas secciones en diferentes nombres de variables como base de datos y usuarios.

Ahora, al usar for loop, iteramos en estas secciones e imprimimos estos valores para verificar si obtenemos lo que queremos.

Implementar una conexión hacia MySQL, PostegreSQL y Oracle DB.

Vamos a crear un archivo config.py que lea el archivo .ini creado mediante la función def config() que devolverá los parámetros de conexión en una variable «db»:

from configparser import ConfigParser


def config(filename='database.ini', section='postgresql'):
    # create a parser
    parser = ConfigParser()
    # read config file
    parser.read(filename)

    # get section, default to postgresql
    db = {}
    if parser.has_section(section):
        params = parser.items(section)
        for param in params:
            db[param[0]] = param[1]
    else:
        raise Exception('Section {0} not found in the {1} file'.format(section, filename))

    return db

Importaremos esta función desde el archivo creado config.py en el código de Python que utilizaremos para conectarnos a la base de datos a través de psycopg2, en este caso a PostgreSQL, al que podremos llamar connect.py:

import psycopg2
from config import config

def connect():
    """ Connect to the PostgreSQL database server """
    conn = None
    try:
        # read connection parameters
        params = config()

        # connect to the PostgreSQL server
        print('Connecting to the PostgreSQL database...')
        conn = psycopg2.connect(**params)
		
        # create a cursor
        cur = conn.cursor()
        
	# execute a statement
        print('PostgreSQL database version:')
        cur.execute('SELECT version()')

        # display the PostgreSQL database server version
        db_version = cur.fetchone()
        print(db_version)
       
	# close the communication with the PostgreSQL
        cur.close()
    except (Exception, psycopg2.DatabaseError) as error:
        print(error)
    finally:
        if conn is not None:
            conn.close()
            print('Database connection closed.')


if __name__ == '__main__':
    connect()

Al correr guardará los valores devueltos en db en la variable params la cual se utilizará para generar la conexión. El script nos devolverá el estado de conexión con éxito, la versión de PostgreSQL instalada y el sistema operativo sobre el cual corre.

A partir de aquí ya puedes realizar tus consultas SQL a través del cursor «cur».

Importante recordar que una vez realizadas las consultas requeridas debes cerrar el cursos y la conexión a la base de datos a través de .close() para ambos casos.

Si quieres conectar a una base de datos MySQL podrás utilizar los mismos archivos creados database.ini y connect.py, utilizando en este caso el conector mysql.connector el cual deberás instalar en tu equipo o servidor:

pip install mysql-connector
import mysql.connector
from config_mysql import config

def connect():
    """ Connect to the MySQL database server """
    conn = None
    try:
        # read connection parameters
        params = config()

        # connect to the MySQL server
        print('Connecting to the MySQL database...')
        conn = mysql.connector.connect(**params)
		
        # create a cursor
        cur = conn.cursor()
        
	# execute a statement
        print('MySQL database version:')
        cur.execute('SELECT VERSION()')

        # display the MySQL database server version
        db_version = cur.fetchone()
        print(db_version)
       
	# close the communication with the MySQL
        cur.close()
    except (Exception, mysql.connector.Error) as error:
        print(error)
    finally:
        if conn is not None:
            conn.close()
            print('Database connection closed.')


if __name__ == '__main__':
    connect()

Finalmente si vas a conectarte a una base de datos de Oracle deberas instalar y utilizar el conector oracledb y hacer la importación en el script de Python:

pip install oracledb

En este caso te recomiendo seguir este tutorial de Oracle para conectar con sus bases de datos a través de Python.

Automatizando con Ansible: del localhost al servidor de producción.

Ansible es una plataforma de software libre para configurar y administrar ordenadores. Combina instalación multi-nodo, ejecuciones de tareas ad hoc y administración de configuraciones. Adicionalmente, Ansible es categorizado como la herramienta de orquestación mas utilizada al dia de hoy.​

Para su instalación, que no es complicada, y su configuración, se deben seguir los lineamientos de la documentación según sea la distro sobre la cual se ha instalado.

Para realizar una instalación en Ubuntu se pueden utilizar los siguientes comandos:

$ sudo apt update
$ sudo apt install software-properties-common
$ sudo add-apt-repository --yes --update ppa:ansible/ansible
$ sudo apt install ansible

Luego de su descarga y su instalaciónm Ansible se ubica en el directorio /etc/ansible donde encontrarás el archivo de configuración ansible.cfg el cual albergará los plugins que instales con posterioridad, y el archivo hosts define los hosts y grupos de hosts en los que funcionan los comandos, módulos y tareas de un manual. Para comprender más sencillamente los hosts hacen referencia a los dominios y direcciones IP de tus servidores. Incluso a modo de prueba puedes agregar tu equipo como localhost para agregarlo a las configuraciones automatizadas.

De previo a agregar un servidor al archivo hosts es recomendable que tengas autorizado el acceso al servidor que vayas a agregar como hosts mediante ssh-keygen. En todo caso, también puedes configurar el acceso a tu servidor mediante la definición de ansible_user y ansible_password en dicho archivo, aunque no es lo mas recomendable.

Un ejemplo de configuración del archivo hosts puede contener una dirección IP o un dominio, ambos referidos al servidor que se va a automatizar, o bien ambos., como el siguiente:

[webservers]
107.175.219.151
localhost

Si no has configurado las claves ssh puedes agregar las credenciales así:

[webservers]
107.175.219.151 ansible_user=root ansible_password=password
localhost ansible_user=root ansible_password=password 

Esta configuración incluye tanto acciones sobre un servidor que se accesa mediante la dirección IP 107.175.219.151 y tu propio equipo, pero puedes agregar mas direciones IP o dominios que apunten a otros servidores.

Ahora intentaremos conectar a los hosts con el comando ping, verificar que haya un python utilizable y esperar el regreso de pong en caso de éxito.

Si tenemos una respuesta satisfactoria leeremos success y la leyenda en verde, en caso contrario que exista algún problema de configuración, credenciales o conexión nos dará el aviso de fallo con la leyenda en rojo.

Comandos ad hoc

Un comando ad hoc de Ansible utiliza la herramienta de línea de comandos /usr/bin/ansible para automatizar una sola tarea en uno o más nodos administrados. los comandos ad hoc son rápidos y fáciles, pero no son reutilizables. Su importancia radica en que se utilizarán o transferirán directamente a los archivos playbook que los verdaderos protagnistas de Ansible, y que los veremos de seguido.

De rigor es importante remitirse a la documentación, para comprender su uso, que siguie esta regla:

$ ansible [pattern] -m [module] -a "[module options]"

El siguiente ejemplo verifica que el editor vim este instalado en su equipo y de no estarlo procede a su descarga y configuración.

Es importante notar que una vez que se ha cumplido con la instalación, en el siguiente llamado del módulo simplemente indicará que ya se ha cumplido con este proceso.

Aquí es donde entra la automatización e inicia la utilidad de Ansible pues puedes definir muchas tareas como:

Para esto es donde ocupamos los archivos playbook cuya extensión es .yml y se crean en el mismo directorio /etc/ansible.

Esta página proporciona una descripción general básica de la sintaxis YAML correcta, que es cómo se expresan los playbooks de Ansible (el lenguaje de gestión de configuración).

Se utiliza YAML porque es más fácil de leer y escribir para los humanos que otros formatos de datos comunes como XML o JSON. Además, hay bibliotecas disponibles en la mayoría de los lenguajes de programación para trabajar con YAML.

Un ejemplo sencillo que utiliza los hosts que hemos defindo como ejemplo anteriormente puede ser:

---
- hosts: webservers
  tasks:
     - name: Actualizar cache de paquetes
       apt: 
         update_cache: yes
         become: true
     - name: Instalar nmap
       apt: 
         name: nmap
         state: latest
         become: true
       

Este archivo define el grupo webservers (localhost y remoto) como el destino del script, define dos tareas a realizar que es la actualización del caché de paquetes y la instalación de la libreria nmap en ambos servidores a través del módulo apt.

Cómo el módulo apt requiere permisos de superusuario administrador eventualmente se debe agregar become: true al script y el parámetro -K para que se nos solicite la respectiva contraseña en caso que el acceso SSH no sea con el administrador. En caso contrario no habrà ningun problema en correr el script tal y como se ha definido.

Finalmente, en este repositorio encontrarás mas ejemplos de playbooks sencillos con los cuales puedes iniciar tus configuraciones de servidores con Ansible.

Sed, el editor de secuencias, y un poco de expresiones regulares. Sys Admin y DevOps.

El comando SED en UNIX significa editor de flujo y puede realizar muchas funciones en el archivo, como buscar, encontrar y reemplazar, insertar o eliminar. Aunque el uso más común del comando SED en UNIX es para sustitución o para buscar y reemplazar. Al usar SED, puede editar archivos incluso sin abrirlos, que es una forma mucho más rápida de encontrar y reemplazar algo en el archivo, que primero abrir ese archivo en VI Editor y luego cambiarlo.

  • SED es un potente editor de secuencias de texto. Puede hacer inserción, eliminación, búsqueda y reemplazo (sustitución).
  • El comando SED en Unix admite la expresión regular, lo que le permite realizar coincidencias de patrones complejos.

Sintaxis

OPCIONES sed... [GUIÓN] [ARCHIVO DE ENTRADA...] 

Ejemplo:
considere el siguiente archivo de texto como una entrada.

$cat > file.txt
Unix es un gran sistema operativo. Unix es de código abierto. Unix es un sistema operativo libre.
aprender sistema operativo.
unix linux cuál eliges.
unix es fácil de aprender.unix es un sistema operativo multiusuario.Aprender unix .unix es un poderoso.

Reemplazar o sustituir una cadena: el comando Sed se usa principalmente para reemplazar el texto en un archivo. El siguiente comando sed simple reemplaza la palabra «unix» con «linux» en el archivo.

$sed 's/unix/linux/' file.txt
linux es un gran sistema operativo. Unix es de código abierto. Unix es un sistema operativo libre.
aprender sistema operativo.
linux linux cuál eliges.
linux es fácil de aprender.unix es un sistema operativo multiusuario.Aprender unix .unix es poderoso.
Aquí la “s” especifica la operación de sustitución. Los “/” son delimitadores. El "unix" es el patrón de búsqueda y el "linux" es la cadena de reemplazo.

De forma predeterminada, el comando sed reemplaza la primera ocurrencia del patrón en cada línea y no reemplazará la segunda, tercera... ocurrencia en la línea.

Reemplazo de la enésima ocurrencia de un patrón en una línea: Use las banderas /1, /2, etc. para reemplazar la primera, segunda ocurrencia de un patrón en una línea. El siguiente comando reemplaza la segunda aparición de la palabra «unix» con «linux» en una línea.

$sed 's/unix/linux/2' file.txt
Unix es un gran sistema operativo. Linux es de código abierto. Unix es un sistema operativo libre.
aprender sistema operativo.
unix linux cuál eliges.
Unix es fácil de aprender. Linux es un sistema operativo multiusuario. Aprenda Unix. Unix es un poderoso.

Reemplazo de todas las ocurrencias del patrón en una línea: el indicador de sustitución /g (reemplazo global) especifica el comando sed para reemplazar todas las ocurrencias de la cadena en la línea.

$sed 's/unix/linux/g' file.txt
linux es un gran sistema operativo. Linux es de código abierto. linux es un sistema operativo libre.
aprender sistema operativo.
linux linux cuál eliges.
linux es fácil de aprender. linux es un sistema operativo multiusuario. Aprenda linux. linux es un poderoso.

Reemplazar desde la enésima aparición a todas las apariciones en una línea: use la combinación de /1, /2, etc. y /g para reemplazar todos los patrones desde la enésima aparición de un patrón en una línea. El siguiente comando sed reemplaza la tercera, cuarta, quinta… palabra «unix» con la palabra «linux» en una línea.

$sed 's/unix/linux/3g' file.txt
Unix es un gran sistema operativo. Unix es de código abierto. linux es un sistema operativo libre.
aprender sistema operativo.
unix linux cuál eliges.
unix es fácil de aprender.unix es un sistema operativo multiusuario.Aprender linux .linux es un poderoso.

Como vemos, el comando Sed es muy útil para realizar operaciones de búsqueda y reemplazo de patrones de texto.

Expresiones Regulares (RE)

Veamos ahora un ejemplo de cómo utilizar Espresiones Regulares con el comando Sed.

Colocar entre paréntesis el primer carácter de cada palabra: este ejemplo de sed imprime el primer carácter de cada palabra entre paréntesis.

$ echo "Bienvenido al mundo de Linux" | sed 's/\b\([a-zA-Z]\)/(\1)/g'

La expresión regular ‘s/\b([a-zA-Z])/(\1)/g’ se puede interpretar de la siguiente manera:

  • La letra ‘s’ al principio indica que se trata de una operación de reemplazo (substitución).
  • El primer conjunto de caracteres dentro de las barras inclinadas (‘/’) representa el patrón de búsqueda a ser reemplazado. En este caso, el patrón de búsqueda es ‘\b\([a-zA-Z]\)’, que busca un carácter de palabra que sea una letra mayúscula o mayúscula al inicio de una palabra.
  • El segundo conjunto de caracteres dentro de las barras inclinadas (‘/’) representa el texto de reemplazo. En este caso, el texto de reemplazo es ‘(\1)’, que reemplaza el patrón de búsqueda con la misma letra mayúscula que se encontró, pero esta vez entre paréntesis.
  • La letra ‘g’ al final indica que se debe realizar la operación de reemplazo en todas las instancias encontradas en el texto, no sólo en la primera.

Entonces, esta expresión regular busca todas las letras mayúsculas que comienzan una palabra y las reemplaza por la misma letra entre paréntesis.

Con el comando Sed puedes realizar un gran número de modificaciones y sustituciones de texto, incluso también se puede usar para eliminar líneas de un archivo en particular. 

Para que conozcas más sobre la sintaxis de este comando y su uso con expresiones regulares tanto básicas (BRE) como extendidas (ERE) te recomendamos que visites la documentación de GNU al respecto.