Node.js: Drucken auf der Konsole ohne nachgestellten Zeilenumbruch?


682

Gibt es eine Methode zum Drucken auf der Konsole ohne nachgestellten Zeilenumbruch? Die consoleObjekt - Dokumentation sagt nichts über das:

console.log()

Druckt mit Zeilenumbruch nach Standard. Diese Funktion kann mehrere Argumente auf printf()ähnliche Weise annehmen . Beispiel:

console.log('count: %d', count);

Wenn in der ersten Zeichenfolge keine Formatierungselemente gefunden werden, util.inspectwird für jedes Argument verwendet.

Antworten:


1056

Sie können verwenden process.stdout.write():

process.stdout.write("hello: ");

Einzelheiten finden Sie in den Dokumenten .


7
Dies löste das gegenteilige Problem für mich. console.logdruckte \nbuchstäblich, als ich wollte, dass es ein Zeilenumbruchzeichen druckt.
Paul

@Paulpro ist nicht '\ n' das Newline-Zeichen?
Alexander Mills

3
@AlexMills Dies ist die Escape-Sequenz für ein Zeilenumbruchzeichen, aber selbst kein Zeilenumbruchzeichen. Ich bekam ein wörtliches ` followed by an n`, als ich einen echten Zeilenumbruch ausgeben wollte.
Paul

378

Wenn Sie Nachrichten in derselben Zeile überschreiben möchten, z. B. in einem Countdown, können Sie am Ende der Zeichenfolge '\ r' hinzufügen.

process.stdout.write("Downloading " + data.length + " bytes\r");

18
Obwohl dies nicht die Antwort auf die Frage ist, ist dies eine erstaunliche Antwort. Ich kann es kaum erwarten, es zu versuchen.
Longda

8
Dies gilt nicht funktioniert unter Windows für mich. Funktioniert aber hervorragend bei Nicht-Dows.
Chowey

45
Für Windows können Sie den entsprechenden Code '\ 033 [0G' verwenden, wie in:process.stdout.write("Downloading " + data.length + " bytes\033[0G");
GarciadelCastillo

19
Um das zu machen ansi Escape - Code oben in einem Kommentar von @GarciadelCastillo zur Arbeit im strikten Modus gegeben, ersetzen die Oktal wörtliche \033mit dem Hex - wörtlichen \x1bwie folgt aus : \x1b[0G. (das funktioniert sowohl mit striktem als auch mit nicht striktem Code)
einige

7
Setzen Sie das \ r einfach am Anfang und nicht am Ende der Zeichenfolge, damit es unter Windows funktioniert.
Daremkd

20

In der Windows-Konsole (auch Linux) sollten Sie '\r'den entsprechenden Code ersetzen \033[0G:

process.stdout.write('ok\033[0G');

Dies verwendet eine Escape-Sequenz für das VT220-Terminal, um den Cursor in die erste Spalte zu senden.


1
Wie würden Sie mehrere Zeilen anstatt nur der aktuellen Zeile sichern? Das Top- Programm scheint in der Lage zu sein, meinen gesamten Puffer während der Ausführung zu überschreiben und das wiederherzustellen, was vorhanden war, als es fertig war. Weiß jemand wie es das macht? i.imgur.com/AtCmEjn.gif
Chev

Ich glaube, es wird wahrscheinlich so etwas wie eines davon verwendet: github.com/mscdex/node-ncurses github.com/chjj/blessed
Brandon

1
Es funktioniert, aber ich bekomme den Cursor auch gerne [\] 39und der Cursor wird auf dem ersten var spinner = '|/-\\'.split('');process.stdout.write("["+this.randomElement(spinner)+"] "+message+"\033[0G");
Zeichen

1
@Chev Top ist etwas Besonderes und kann nicht mit ANSI-Escape-Codes geschrieben werden. Es verwendet in der Tat ncurses, weshalb Sie es nicht auf eingebetteten Systemen finden, die keine großen C-Bibliotheken haben
cat

1
@Chev: Die meisten Leute werden Sie aufgrund ihrer eigenen FUD davon abhalten, mit fest codierten Escape-Sequenzen zu spielen, aber fast jeder verwendet jetzt VT100, sodass Kompatibilität kein Problem mehr darstellt. Die Funktionalität, auf die Sie sich beziehen, ist das Verhalten "alternativer Bildschirm". Ein grundlegendes Intro finden Sie in man console_codes(unter Linux oder online) und meine Lieblingsreferenz ist www2.phys.canterbury.ac.nz/dept/docs/manuals/unix/DEC_4.0e_Docs/… (99% des Inhalts funktionieren noch) . Einziger Vorbehalt: Seien Sie bereit, Experimente an mehreren verschiedenen Terminals zu testen, bevor Sie sie in großem Umfang einsetzen.
i336_

18

Als Erweiterung / Erweiterung der brillanten Ergänzung von @rodowi oben bezüglich der Möglichkeit, eine Zeile zu überschreiben:

process.stdout.write("Downloading " + data.length + " bytes\r");

Wenn Sie nicht möchten, dass sich der Terminalcursor beim ersten Zeichen befindet, wie ich in meinem Code gesehen habe, sollten Sie Folgendes tun:

let dots = ''
process.stdout.write(`Loading `)

let tmrID = setInterval(() => {
  dots += '.'
  process.stdout.write(`\rLoading ${dots}`)
}, 1000)

setTimeout(() => {
  clearInterval(tmrID)
  console.log(`\rLoaded in [3500 ms]`)
}, 3500)

Durch Platzieren der \rvor der nächsten print-Anweisung wird der Cursor zurückgesetzt, kurz bevor die ersetzende Zeichenfolge die vorherige überschreibt.


13

util.print kann auch verwendet werden. Lesen Sie: http://nodejs.org/api/util.html#util_util_print

util.print ([...]) # Eine synchrone Ausgabefunktion. Blockiert den Prozess, wandelt jedes Argument in eine Zeichenfolge um und gibt es an stdout aus. Platziert keine Zeilenumbrüche nach jedem Argument.

Ein Beispiel:

// get total length
var len = parseInt(response.headers['content-length'], 10);
var cur = 0;

// handle the response
response.on('data', function(chunk) {
  cur += chunk.length;
  util.print("Downloading " + (100.0 * cur / len).toFixed(2) + "% " + cur + " bytes\r");
});

39
util.printist jetzt veraltet
Petr Peller

(node:7616) DeprecationWarning: util.print is deprecated. Use console.log instead.
Grün

10

Es scheint viele Antworten zu geben, die darauf hindeuten:

process.stdout.write

Fehlerprotokolle sollten ausgegeben werden auf:

process.stderr

Verwenden Sie stattdessen:

console.error

Für alle, die sich fragen, warum process.stdout.write('\033[0G');sie nichts getan haben, liegt es daran, dass stdoutes gepuffert ist und Sie auf das drainEreignis warten müssen ( weitere Informationen ).

Wenn write zurückgibt false, wird ein drainEreignis ausgelöst.


4

Keine dieser Lösungen arbeiten für mich, process.stdout.write('ok\033[0G')und mit nur '\r'gerade eine neue Linie erstellen , aber nicht überschreiben auf Mac OSX 10.9.2.

EDIT: Ich musste dies verwenden, um die aktuelle Zeile zu ersetzen:

process.stdout.write('\033[0G');
process.stdout.write('newstuff');

4

Bei Verwendung des strengen Modus wurde folgende Fehlermeldung angezeigt:

Knotenfehler: "Oktal-Literale sind im strengen Modus nicht zulässig."

Die folgende Lösung funktioniert ( Quelle ):

process.stdout.write("received: " + bytesReceived + "\x1B[0G");

Ändern Sie das ocltal Literal tobsone.orher numerisches Format
FrancescoMM
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.