Saltar la navegación

Comando x (exchange)

El comando x (exchange) intercambia el contenido de las zonas de trabajo y auxiliar.

Como ejemplo vamos a encerrar entre llaves todos los párrafos del flujo de entrada:

$ echo -e "a\na\n\nb\n\nc"
a
a

b

c
$ echo -e "a\na\n\nb\n\nc" | sed '/./{s/^/  / ; H ; $!d} ; x ; s/^/{/ ; s/$/\n}/'
{
  a
  a
}
{
  b
}
{
  c
}

Lo que se ha hecho es lo siguiente:

  1. El primer agrupamiento actuará solo sobre líneas que contienen algo, no actuará sobre las líneas de separación de párrafos. (/./{ ... })
    1. Indentamos las líneas añadiendo dos espacios al inicio de estas. (s/^/  /)
    2. Añadimos la línea a la zona auxiliar con un \n. (H)
    3. Borramos la línea siempre y cuando no sea la última del flujo de entrada. El objetivo fundamental de este comando es iniciar el ciclo, con lo que conseguimos que el resto de comandos no se ejecuten. Estamos haciendo un control de flujo dentro del script, una especie de mientras la línea no sea vacía, se ejecutará solo el agrupamiento, cuando se alcance una línea vacía se continúa con el script. ($!d)
  2. Intercambiamos las zonas de trabajo y auxiliar. En la zona auxiliar habrá un línea vacía y en la zona de trabajo estarán todas las líneas del párrafo. A este punto solo se llega si el comando d no se ejecuta, y eso solo sucede en dos situaciones, cuando la línea es una línea vacía o es la última del flujo de entrada. (x)
  3. Al inicio de la zona de trabajo se inserta el carácter {, un \n no es necesario insertarlo pues ya lo insertó el comando H. (s/^/{/)
  4. Al final de la zona de trabajo se insertan los caracteres } y \n. (s/$/}\n/)

Para reflexionar, aquí va otra forma de hacer lo mismo:

$ echo -e "a\na\n\nb\n\nc" | sed -n -e '/./{s/^/  / ; H ; $!d} ; x ; i {' -e 's/^\n// ; p ; a }'
{
a
a
}
{
b
}
{
c
}