cat <<EOS | sed -ne '1{h;d;}' -e 'H;${G;p;}'
line 1
line 2
line 3
EOS
El problema con traducir esto a algo que usa tailes que tailnecesita leer todo el archivo para encontrar el final. Para usar eso en su tubería, necesita
- Proporcione el contenido completo del documento a
tail.
- Proporcionar de nuevo a
cat.
- En ese orden.
La parte difícil no es duplicar el contenido del documento (lo teehace) sino lograr que la salida tailsuceda antes de que salga el resto del documento, sin usar un archivo temporal intermedio.
El uso sed(o awk, como lo hace John1024 ) elimina el doble análisis de los datos y el problema de ordenar almacenando los datos en la memoria.
La sedsolución que propongo es
1{h;d;}, almacene la primera línea en el espacio de espera, tal cual, y salte a la siguiente línea.
H, agregue entre sí la línea al espacio de espera con una nueva línea incrustada.
${G;p;}, agregue el espacio de espera a la última línea con una nueva línea incrustada e imprima los datos resultantes.
Esta es una traducción bastante literal de la solución de John1024 sed, con la advertencia de que el estándar POSIX solo garantiza que el espacio de retención sea de al menos 8192 bytes (8 KiB; pero recomienda que este búfer se asigne dinámicamente y se expanda según sea necesario, lo que tanto GNU sedy BSD lo sedestá haciendo).
Si te permites usar una tubería con nombre:
mkfifo mypipe
cat <<EOS | tee mypipe | cat <( tail -n 1 mypipe ) -
line 1
line 2
line 3
EOS
rm -f mypipe
Esto se utiliza teepara enviar los datos hacia abajo mypipey al mismo tiempo a cat. La catutilidad primero leerá la salida de tail(que lee mypipe, que teeestá escribiendo), y luego agregará la copia del documento que viene directamente tee.
Sin embargo, hay una falla grave en esto, ya que si el documento es demasiado grande (más grande que el tamaño del búfer de la tubería), teela escritura mypipey el catbloqueo se bloquearán mientras se espera que la tubería (sin nombre) se vacíe. No se vaciaría hasta que se catleyera. catno leería de él hasta que tailhubiera terminado. Y tailno terminaría hasta que teehubiera terminado. Esta es una situación clásica de punto muerto.
La variación
tee >( tail -n 1 >mypipe ) | cat mypipe -
tiene el mismo problema