Redirigir la salida que envía spam al terminal con retornos de carro

Redirigir la salida que envía spam al terminal con retornos de carro

Tengo un comando que crea una salida muy detallada, del orden de cientos de líneas por segundo. Sin embargo, el comando se utiliza \rpara sobrescribir la línea de salida anterior, de forma similar a una barra de progreso. De vez en cuando escribe una nueva línea en la terminal, que "hornea" la línea de salida actual.

Al redirigir esta salida a un archivo, obtengo cientos de megas de salida: cada línea se escribe en el archivo, en lugar de "sobrescribirse" cuando se produce el retorno de carro.

Entiendo que este es el comportamiento esperado y que una forma de resolverlo sería hacer que el programa sea más inteligente y darme cuenta de que está siendo redirigido al archivo y no imprimir este estado interactivo. Sin embargo, no puedo modificar este programa.

¿Hay alguna manera de canalizar/filtrar esta salida para que lo que termine en el archivo de salida final sea lo mismo que vería si lo ejecutara de forma interactiva en la terminal?

He intentado:

spammy_cr_command | uniq

... que produce lo mismo que sinuniq

y también:

spammy_cr_command | sed '/\r/d'

... que también elimina las líneas "preparadas" que contienen el carácter de nueva línea.

Respuesta1

cmd | sed -e 's/.*\r//' > file

Esto reemplazará todo el texto en cada línea seguida por un retorno de carro sin nada, dejando solo la parte de la línea después del retorno de carro final. Esto no esnecesariamenteSin embargo, es lo mismo que quedaría en la terminal, pero es una aproximación cercana la mayor parte del tiempo.


En particular, no se maneja el caso en el que una línea es más larga que su sucesora. Este programa daría resultados incorrectos:

printf 'abcdefg\rxyz\n'
printf '123456789\r\nxyz\n'

porque lo que quedaría visiblemente atrás es

xyzdefg
123456789
xyz

pero sedtambién omitiría todos los caracteres no borrados y daría

xyz

xyz

Puede determinar si su programa se comporta así o no. No es raro que las barras de progreso y similares coloquen el cursor en el borde izquierdo, lo que puede no dar el resultado deseado.

Respuesta2

Para una salida TTY-37 muy primitiva, el colcomando resuelve esto sin los problemas sedmencionados en la respuesta de M. Homer. (Para la salida que no es una simple salida TTY-37 y contiene secuencias de control y escape de terminal, ninguna colde las dos sedes la herramienta para el trabajo; pero Stack Exchange ha tenido una sesión de preguntas y respuestas sobreesodesde hace casi ocho años.)

%(
printf 'abcdefg\rxyz\n'
printf '123456789\r\nxyz\n'
) | col -b
xyzdefg
123456789
xyz
%

Respuesta3

Se puede hacer algo más parecido al comportamiento de sobrescritura con GNU awk:

BEGIN { 
  RS = "[\r\n]"                   # split records on either CR or LF
  a = ""                          # variable to save the text for overwriting
} 
{
  a = $0 substr(a, 1 + length)    # save current line, add trailing part of saved text
} 
RT ~ /\n/ {                       # LF, time to print and reset
  print a;
  a = ""
}

Usando el ejemplo de Michael Homer:

~ awk 'BEGIN { RS="[\r\n]" } {a = $0 substr(a, 1 + length)} RT ~ /\n/ {print a; a=""}' foo
xyzdefg
123456789
xyz

Se necesita GNU awk para la RTvariable, que contiene el texto separador de registros que coincide con la RSexpresión regular de ese registro.

información relacionada