Node.js: imprimer sur une console sans retour à la ligne?

683

Existe-t-il une méthode d'impression sur la console sans retour à la ligne de fin? La documentation de l'console objet ne dit rien à ce sujet:

console.log()

Imprime à la sortie standard avec la nouvelle ligne. Cette fonction peut prendre plusieurs arguments de la même printf()manière. Exemple:

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

Si des éléments de formatage ne sont pas trouvés dans la première chaîne, ils util.inspectsont utilisés pour chaque argument.

Evan Carroll
la source

Réponses:

1058

Vous pouvez utiliser process.stdout.write():

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

Voir les documents pour plus de détails .

onteria_
la source
7
Cela a résolu le problème inverse pour moi. console.logimprimait \nlittéralement quand je voulais qu'il imprime un caractère de nouvelle ligne.
Paul
@Paulpro n'est pas '\ n' le caractère de la nouvelle ligne?
Alexander Mills
3
@AlexMills C'est la séquence d'échappement d'un caractère de nouvelle ligne, mais ce n'est pas un caractère de nouvelle ligne lui-même. ` followed by an J'obtenais un littéral n`, quand je voulais sortir un vrai caractère de nouvelle ligne.
Paul
379

De plus, si vous souhaitez remplacer les messages sur la même ligne, par exemple dans un compte à rebours, vous pouvez ajouter «\ r» à la fin de la chaîne.

process.stdout.write("Downloading " + data.length + " bytes\r");
defvol
la source
18
Bien que ce ne soit pas la réponse à la question, c'est une réponse étonnante. J'ai hâte d'essayer.
longda
8
Cela ne fonctionne pas sur Windows pour moi. Mais fonctionne très bien sur les non-dows.
chowey
45
Pour Windows, vous pouvez utiliser le code équivalent '\ 033 [0G', comme dans:process.stdout.write("Downloading " + data.length + " bytes\033[0G");
GarciadelCastillo
19
Pour rendre le code d'échappement ansi donnée ci - dessus dans un commentaire par @GarciadelCastillo au travail en mode strict, remplacer le littéral octal \033avec le littéral hexadécimal \x1bcomme ceci: \x1b[0G. (qui fonctionne avec du code strict et non strict)
du
7
Mettez simplement le \ r au début plutôt qu'à la fin de la chaîne pour le faire fonctionner sous Windows.
daremkd
20

Dans la console Windows (Linux aussi), vous devez remplacer '\r'par son code équivalent \033[0G:

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

Celui-ci utilise une séquence d'échappement du terminal VT220 pour envoyer le curseur à la première colonne.

Yan Te
la source
1
Comment remonteriez-vous plusieurs lignes au lieu de simplement la ligne actuelle? Le programme supérieur semble pouvoir remplacer tout mon tampon pendant qu'il est en cours d'exécution et restaure ce qui était là quand il est terminé. Quelqu'un sait-il comment cela fonctionne? i.imgur.com/AtCmEjn.gif
Chev
Je crois qu'il utilise probablement quelque chose comme l'un d'eux: github.com/mscdex/node-ncurses github.com/chjj/blessed
Brandon
1
Cela fonctionne mais j'obtiens le curseur aussi bien [\] 39et le curseur est mis en évidence sur le premier caractère:var spinner = '|/-\\'.split('');process.stdout.write("["+this.randomElement(spinner)+"] "+message+"\033[0G");
loretoparisi
1
@Chev Top est spécial, pas quelque chose que vous pouvez écrire avec des codes d'échappement ANSI. Il utilise en effet ncurses, c'est pourquoi vous ne le trouverez pas sur les systèmes embarqués qui n'ont pas de grandes librairies C
cat
1
@Chev: La plupart des gens vous dissuaderont de jouer avec des séquences d'échappement codées en dur en raison de leur propre FUD, mais presque tout le monde utilise le VT100 maintenant, donc la compatibilité n'est plus vraiment un problème. La fonctionnalité à laquelle vous faites référence est le comportement "écran alternatif". Une introduction de base peut être trouvée dans man console_codes(sous Linux ou en ligne) et ma référence préférée est www2.phys.canterbury.ac.nz/dept/docs/manuals/unix/DEC_4.0e_Docs/… (99% de son contenu fonctionne toujours) . Seul bémol: soyez prêt à tester toutes les expériences sur plusieurs terminaux différents avant de déployer largement.
i336_
18

En tant qu'extension / amélioration de l'ajout brillant fait par @rodowi ci-dessus concernant la possibilité de remplacer une ligne:

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

Si vous ne souhaitez pas que le curseur du terminal se trouve au premier caractère, comme je l'ai vu dans mon code, envisagez de faire ce qui suit:

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)

En plaçant le \rdevant de l'instruction d'impression suivante, le curseur est réinitialisé juste avant que la chaîne de remplacement n'écrase la précédente.

mraxus
la source
13

util.print peut également être utilisé. Lire: http://nodejs.org/api/util.html#util_util_print

util.print ([...]) # Fonction de sortie synchrone. Bloque le processus, transforme chaque argument en chaîne, puis le renvoie vers stdout. Ne place pas de nouvelle ligne après chaque argument.

Un exemple:

// 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");
});
douyw
la source
39
util.printest désormais obsolète
Petr Peller
(node:7616) DeprecationWarning: util.print is deprecated. Use console.log instead.
Vert
10

Il semble y avoir de nombreuses réponses suggérant:

process.stdout.write

Les journaux d'erreurs doivent être émis sur:

process.stderr

Utilisez plutôt:

console.error

Pour tous ceux qui se demandent pourquoi process.stdout.write('\033[0G');ne font rien, c'est parce qu'ils stdoutsont tamponnés et que vous devez attendre l' drainévénement ( plus d'informations ).

Si l'écriture revient, falseil déclenchera un drainévénement.

Ahmed Masud
la source
5

Aucune de ces solutions ne fonctionne pour moi process.stdout.write('ok\033[0G')et il '\r'suffit de créer une nouvelle ligne mais de ne pas l'écraser sur Mac OSX 10.9.2.

EDIT: J'ai dû l'utiliser pour remplacer la ligne actuelle:

process.stdout.write('\033[0G');
process.stdout.write('newstuff');
Tyguy7
la source
4

J'ai eu l'erreur suivante lors de l'utilisation du mode strict:

Erreur de nœud: "Les littéraux octaux ne sont pas autorisés en mode strict."

La solution suivante fonctionne ( source ):

process.stdout.write("received: " + bytesReceived + "\x1B[0G");
blablabla
la source
Changer le format numérique ocbsal tobsone.orher
FrancescoMM