Con el comando b (branch) provocamos un salto incondicional a una etiqueta del script sin reiniciar el ciclo de sed. Su sintaxis es la siguiente:
b [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 el comando b cuando lleva etiqueta no reinicia el ciclo, se suele utilizar dentro del bucle los comandos n y/o N para poder avanzar con el flujo de entrada.
Si este comando va acompañado de un ámbito, el salto se convertiría en condicional. Podemos usar esto para crear bucles:
:salto
comando1
comando2
...
comandoN
ámbito b salto
:salto1
ámbito b salto2
comando1
comando2
...
comandoN
b salto1
:salto2
El siguiente script de bash usa la orden sed para mostrar la información del flujo de entrada con la anchura deseada.
#!/bin/bash
declare longitud fichero script
if [ -z "$1" ]; then
echo "Uso: muestra longitudDeLinea fichero" 1>&2
exit 1
else
suma=$(($1 + 1))
if [ $suma -lt 2 ]; then
echo "Error: La longitud de la línea debe ser >= 1" 1>&2
echo "Uso: muestra longitudDeLinea fichero" 1>&2
exit 2
else
longitud=$1
fi
fi
if [ -z "$2" ]; then
echo "Uso: muestra longitudDeLinea fichero" 1>&2
exit 3
else
if [ "$2" != "-" -a ! -f "$2" ]; then
echo "El fichero '$2' no existe" 1>&2
exit 4
else
fichero=$2
fi
fi
# Nombre del script de sed
script="script-$RANDOM$RANDOM.sed"
# Creamos el script de sed
echo ":nuevaLinea" >> $script # Etiqueta del bucle externo. Al inicio, empieza el ciclo cargando una línea
echo "N" >> $script # Cargamos una nueva línea en la zona de trabajo
echo "s/\n/ /g" >> $script # Sustituimos cada \n por un espacio
echo ":trocear" >> $script # Etiqueta del bucle interno que va haciendo los trozos
echo "s/(.{$longitud})/\1\n/" >> $script # Hacemos el trozo y lo convertimos en línea
echo "/\n/ { P ; s/.*\n// ; b trocear }" >> $script # Todo esto si el trozo se ha hecho
# Visualizamos la primera línea (P)
# La borramos (s/.*\n//)
# Volvemos a trocear si ha texto suficiente (b trocear)
echo "b nuevaLinea" >> $script # Si no se pudieron hacer más trozos saltamos al inicio para cargar otra línea con N
# Ejecutamos sed
sed -E -f $script $fichero
# Borramos el script de sed
rm -f $script
Veamos el script en funcionamiento:
$ ls -l f g
-rw-r--r-- 1 fran fran 13 abr 11 20:38 f
-rw-r--r-- 1 fran fran 7 abr 11 20:38 g
$ ls -l f g | ./muestra.sh 10 -
-rw-r--r--
1 fran fr
an 11 abr
11 10:38 f
-rw-r--r-
- 1 fran f
ran 7 abr
11 12:21
g
$ ls -l f g | ./muestra.sh 15 -
-rw-r--r-- 1 fr
an fran 11 abr
11 10:38 f -rw-
r--r-- 1 fran f
ran 7 abr 11 1
2:21 g
El script de sed concreto para una anchura de 10 caracteres sería así:
:nuevaLinea
N
s/\n/ /g
:trocear
s/(.{10})/\1\n/
/\n/ { P ; s/.*\n// ; b trocear }
b nuevaLinea