En el procesamiento de texto con sed y bash, es fundamental comprender cómo interactuar con variables de shell para automatizar tareas. Este artículo detalla el uso de variables de shell dentro de comandos sed y cómo extraer resultados de sed para configurar variables en el shell.
Uso de Variables de Shell en sed
Las varibales de shell, identificadas con el símbolo $, no pueden ser accedidas directamente por sed sin comillas dobles, ya que sed interpreta el carácter $ de manera especial. Al usar comillas dobles, bash expande las variables antes de que sed procese el comando. Considere un archivo de ejemplo con un marcador de posición:
# Archivo de ejemplo: data.txt
El sistema operativo actual es _os_type_.
# Variable de shell para el tipo de sistema
echo $OS
Linux
Si se utiliza sed con comillas simples, la variable no se expande:
sed 's/_os_type_/$OS/g' data.txt
El sistema operativo actual es $OS.
Para resolver esto, se deben usar comillsa dobles:
sed "s/_os_type_/$OS/g" data.txt
El sistema operativo actual es Linux.
Cuando una variable de shell contiene caracteres especiales, como /, se recomienda utilizar un delimitador alternativo en sed para evitar errores. A continuación, se presentan ejemplos de scripts que integran variables de shell con sed.
Ejemplo 1: Eliminar Líneas Vacías en un Archivo
Este script bash elimina líneas vacías de un archivo especificado. Se utiliza una variable para el nombre del archivo y sed con el comando de eliminación.
#!/bin/bash
# Script para borrar líneas vacías
if [ -z "$1" ]; then
echo "Uso: $0 archivo-objetivo"
exit 1
fi
archivo="$1"
if [ ! -f "$archivo" ]; then
echo "Error: El archivo $archivo no existe."
exit 2
fi
# Patrón para líneas vacías y comando de eliminación
patron='^$'
sed -i "/$patron/d" "$archivo"
echo "Líneas vacías eliminadas en $archivo."
Ejemplo 2: Sustituir Cadenas en un Archivo
Este script reemplaza todas las ocurrencias de una cadena por otra en un archivo. Se pasan los patrones y el nombre del archivo como argumentos.
#!/bin/bash
# Script para reemplazar cadenas
if [ $# -ne 3 ]; then
echo "Uso: $0 patron-antiguo patron-nuevo archivo"
exit 3
fi
viejo="$1"
nuevo="$2"
archivo="$3"
if [ ! -f "$archivo" ]; then
echo "Error: El archivo $archivo no se encontró."
exit 4
fi
# Usar # como delimitador para evitar conflictos
sed -i "s#$viejo#$nuevo#g" "$archivo"
echo "Reemplazo completado en $archivo."
Ejemplo 3: Verificar Origen de Archivos Binarios
Este script examina archivos binarios en un directorio para buscar cadenas específicas, como "Free Software Foundation". Se combinan comandos find, strings, grep y sed.
#!/bin/bash
# Script para analizar binarios
if [ -z "$1" ]; then
echo "Uso: $0 directorio"
exit 5
fi
directorio="$1"
if [ ! -d "$directorio" ]; then
echo "Error: El directorio $directorio no existe."
exit 6
fi
cadena_objetivo="Free Software Foundation"
# Buscar archivos y filtrar con sed
find "$directorio" -type f | while read archivo; do
strings "$archivo" | grep -q "$cadena_objetivo"
if [ $? -eq 0 ]; then
ruta_relativa="${archivo#$directorio/}"
echo "Encontrado en: $ruta_relativa"
fi
done
Ejemplo 4: Formatear Contenido de Correo Electrónico
Este script ajusta el ancho de líneas en un archivo de correo electrónico, eliminando prefijos como ">" y limitando el ancho a un máximo especificado.
#!/bin/bash
# Script para formatear texto de correo
if [ -z "$1" ]; then
echo "Uso: $0 archivo-correo"
exit 7
fi
archivo="$1"
if [ ! -f "$archivo" ]; then
echo "Error: El archivo $archivo no existe."
exit 8
fi
ancho_max=70
# Definir comandos sed en una variable
comandos_sed='
s/^>//
s/^ *>//
s/ *$//
'
# Aplicar sed y ajustar el ancho con fold
sed "$comandos_sed" "$archivo" | fold -s --width=$ancho_max
Configuración de Variables de Shell desde la Salida de sed
sed puede generar salida que se captura en variables de shell mediante sustitución de comandos, facilitando tareas como el renombramiento masivo de archivos.
Ejemplo: Renombrar Archivos en Lote
Este script renombra archivos en el directorio actual, reemplazando una subcadena en los nombres por otra. Se utiliza sed para procesar los nombres y mv para realizar los cambios.
#!/bin/bash
# Script para renombrar archivos
if [ $# -ne 2 ]; then
echo "Uso: $0 patron-antiguo patron-nuevo"
exit 9
fi
antiguo="$1"
nuevo="$2"
contador=0
# Iterar sobre archivos que coinciden con el patrón
for archivo in *"$antiguo"*; do
if [ -f "$archivo" ]; then
nombre_base=$(basename "$archivo")
# Usar sed para crear el nuevo nombre
nombre_nuevo=$(echo "$nombre_base" | sed "s/$antiguo/$nuevo/g")
if [ "$nombre_base" != "$nombre_nuevo" ]; then
mv "$nombre_base" "$nombre_nuevo"
((contador++))
fi
fi
done
if [ "$contador" -eq 1 ]; then
echo "Se renombró 1 archivo."
else
echo "Se renombraron $contador archivos."