Estoy preparando una presentación para una audiencia no técnica. Tengo un programa que se ejecuta en bash que genera un flujo continuo de valores, algunos de los cuales son importantes. Me gustaría resaltar los resultados importantes a medida que se muestran para que el público pueda tener una idea de su frecuencia. El problema es que no puedo sed
operar en una secuencia en ejecución. Funciona bien si pongo los resultados en un archivo, como en:
cat output.txt | sed "s/some text/some text bolded/"
Pero si intento lo mismo en la salida en ejecución, así:
command | sed "s/some text/some text bolded/"
sed
no hace nada. ¿Alguna idea?
Como Lambert fue lo suficientemente útil como para señalar, mi dicho de que sed
no hace nada fue vago. Lo que está sucediendo es que el programa sale stdout
(estoy bastante seguro de que no está escribiendo stderr
) como lo haría normalmente, incluso si se canaliza sed
.
El problema parece ser que el comando llama a un segundo programa, que luego sale a stdout. Hay algunas líneas impresas por el primer programa; Estos puedo editar. Luego hay una corriente de valores impresos por el segundo programa; estos no puedo editarlos.
Los métodos Perl y awk tampoco funcionan.
fuente
stdbuf -o0 command | sed "s/some text/some text bolded/"
?command|egrep 'some text|$'
g
sustitución "global" obtenida, de lo contrario solo se sustituirá la primera aparición en una línea:sed "s/old/new/g"
Respuestas:
Lo más probable es que la salida del comando esté almacenada. Cuando el comando escribe en un terminal, el búfer se vacía en cada nueva línea, por lo que verá que aparece a la velocidad esperada. Cuando el comando escribe en una tubería, el búfer solo se vacía cuando alcanza unos pocos kilobytes, por lo que se retrasa mucho. Por lo tanto, es el comportamiento predeterminado de la biblioteca de entrada / salida estándar.
Para forzar al comando a que no genere un bucle en su salida, puede usar
unbuffer
(desde esperar) ostdbuf
(desde GNU coreutils).fuente
stdbuf
no funcionó (se mencionó anteriormente, por cierto), pero lounbuffer
hizo !! No tienes idea de lo feliz que me has hecho.sed
en sí usa un búfer de este tipo (véase la publicación de ChennyStar), por lo que los ejemplos aquí pueden no funcionar, ya quesed
escommand
para deshacer el búfer:cat /etc/passwd | unbuffer sed
pero ensed
sí tiene una-u
opción, por lo quegrep
podría ser más adecuado en estos ejemplos. Muchas gracias por tu información de fondo! ¡Gran respuesta!sed
tiene una opción para eso:Que carga cantidades mínimas de datos de los archivos de entrada y vacía los búferes de salida con mayor frecuencia. Ver
man sed
para más detalles.fuente
sed
solamente (no BSDsed
), y creo que esto aún no evitaría el almacenamiento en búfer del comando al comienzo de la tubería. Pero es bueno mencionarlo. :)Usaría awk
dónde
/some important stuff/
seleccione una línea importante, como en sedprintf "%c[31m%s%c[0m\n",27,$0,27 ;
imprimir en rojoel punto clave es que
command
debería enjuagar las líneas, pero ese debería ser el caso si tiene mucha salida.fuente
awk
(usandosub()
ogsub()
), en el caso de esta sustitución primitivased
es sin duda la herramienta adecuada.La manera perl:
o con una salida continua:
Un script bash para la salida
cont
:Prueba con:
\x1b[1m
- intensidad audaz o aumentada${1}
- la referencia\x1b[0m
- restablecer todos los atributosSalida:
Más códigos de escape aquí .
fuente