Umleitung der Ausgabe, die das Terminal mit Wagenrückläufen spammt

Umleitung der Ausgabe, die das Terminal mit Wagenrückläufen spammt

Ich habe einen Befehl, der eine sehr ausführliche Ausgabe erzeugt, in der Größenordnung von Hunderten von Zeilen pro Sekunde. Der Befehl überschreibt jedoch \rdie vorherige Ausgabezeile auf eine Weise, die einem Fortschrittsbalken ähnelt. Gelegentlich schreibt er eine neue Zeile in das Terminal, wodurch die aktuelle Ausgabezeile „gebacken“ wird.

Wenn ich diese Ausgabe in eine Datei umleite, erhalte ich eine Ausgabe im Umfang von Hunderten von Megabyte. Jede Zeile wird in die Datei geschrieben, anstatt beim Wagenrücklauf „überschrieben“ zu werden.

Ich verstehe, dass dies das erwartete Verhalten ist und dass eine Möglichkeit, das Problem zu lösen, darin besteht, das Programm intelligenter zu machen und zu erkennen, dass es zur Datei umgeleitet wird, und diesen interaktiven Status nicht auszudrucken. Ich kann dieses Programm jedoch nicht ändern.

Gibt es eine Möglichkeit, diese Ausgabe umzuleiten/filtern, sodass in der endgültigen Ausgabedatei dasselbe enthalten ist, was ich sehen würde, wenn ich es interaktiv auf dem Terminal ausführen würde?

Ich habe es versucht:

spammy_cr_command | uniq

... was dasselbe Ergebnis liefert wie ohneuniq

und auch:

spammy_cr_command | sed '/\r/d'

... wodurch auch die „gebackenen“ Zeilen gelöscht werden, die das Zeilenumbruchzeichen enthalten.

Antwort1

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

Dadurch wird der gesamte Text in jeder Zeile, auf den ein Wagenrücklauf folgt, durch nichts ersetzt, sodass nur der Teil der Zeile nach dem letzten Wagenrücklauf übrig bleibt. Dies ist nichtNotwendigdas Gleiche, was auf dem Terminal hinterlassen würde, ist aber meistens eine gute Annäherung.


Insbesondere wird der Fall nicht behandelt, dass eine Zeile länger ist als ihre Nachfolgerzeile. Dieses Programm würde falsche Ergebnisse liefern:

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

denn was sichtbar zurückbleibt, ist

xyzdefg
123456789
xyz

aber das sedwürde auch alle nicht gelöschten Zeichen überspringen und geben

xyz

xyz

Sie können bestimmen, ob sich Ihr Programm so verhält oder nicht. Es kommt nicht selten vor, dass Fortschrittsbalken und ähnliches den Cursor am linken Rand verharren lassen, was möglicherweise nicht das gewünschte Ergebnis liefert.

Antwort2

Bei sehr primitiven TTY-37-Ausgaben löst der Befehl dies ohne die in M. Homers Antwort erwähnten colProbleme . (Für Ausgaben, die keine einfachen TTY-37-Ausgaben sind und Terminal-Escape- und Steuersequenzen enthalten, sind weder noch das richtige Werkzeug für diese Aufgabe; aber Stack Exchange hatte eine Frage-und-Antwort-Runde zusedcolsedDasseit fast acht Jahren.)

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

Antwort3

Etwas, das dem Überschreibverhalten näher kommt, kann mit GNU awk erreicht werden:

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 = ""
}

Am Beispiel von Michael Homer:

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

GNU awk wird für die RTVariable benötigt, die den Datensatztrenntext enthält, der mit dem RSregulären Ausdruck für diesen Datensatz übereinstimmt.

verwandte Informationen