Con el comando t (test) realizamos un salto condicional a una etiqueta del script sin reiniciar el ciclo de sed. La condición que tiene que cumplirse es que algún comando s previo haya tenido éxito, es decir, que previamente se tiene que haber hecho al menos una sustitución.
La sintaxis es la siguiente:
t [etiqueta]
En el caso de que no se especifique una etiqueta estaríamos forzando el inicio de un nuevo ciclo previo envío de la zona de trabajo a la salida estándar.
Como ejemplo podemos crear un script de sed que elimine todas las líneas en blanco consecutivas:
$ echo -e "\n\n\na\n\n\n\nb\n\n\n\nc\n\n\n"
a
b
c
$ echo -e "\n\n\na\n\n\n\nb\n\n\n\nc\n\n\n" | sed ":inicio; /^$/ { N ; s/\n$// ; t inicio }"
a
b
c
$
Lo que se ha hecho es lo siguiente:
- Si la zona de trabajo está vacía: (/^$/ { ... })
- Cargamos una nueva línea, que puede ser una línea vacía o no. (N)
- Si se ha cargado una línea vacía, el comando s la eliminará, quedándose de nuevo la zona de trabajo vacía. Si se ha cargado otra cosa, este comando no hace nada. (s/\n$//)
- Saltamos al inicio del script si se hizo la sustitución anterior, con lo que se volverá a cumplir el ámbito del punto 1. Si no se hizo la sustitución, este comando no se ejecutará y entonces acaba el ciclo mandando la zona de trabajo a la salida estándar, evidentemente, con una línea distinta a la vacía. (t inicio)
- Si la zona de trabajo no estaba vacía, no se hace nada, simplemente el ciclo termina visualizando la línea.
Observa que si una línea está formada solamente por espacios y/o tabuladores, esa línea no se interpreta como línea vacía, aunque lo parezca:
$ echo -e "a\n\n\n \t\t \n\nb" | sed ":inicio; /^$/ { N ; s/\n$// ; t inicio }"
a
b
Si nos interesara interpretar este tipo de líneas también como líneas vacías, cambiaríamos la expresión regular:
$ echo -e "a\n\n\n \t\t \n\nb" | sed ":inicio; /^\s*$/ { N ; s/\n\s*$// ; t inicio }"
a
b