Node.js: imprimindo no console sem uma nova linha à direita?

682

Existe um método para imprimir no console sem uma nova linha à direita? A documentação doconsole objeto não diz nada sobre isso:

console.log()

Imprime em stdout com nova linha. Esta função pode receber vários argumentos de printf()maneira semelhante. Exemplo:

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

Se os elementos de formatação não forem encontrados na primeira sequência, util.inspectserá usado em cada argumento.

Evan Carroll
fonte

Respostas:

1056

Você pode usar process.stdout.write():

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

Veja os documentos para obter detalhes .

onteria_
fonte
7
Isso resolveu o problema oposto para mim. console.logestava imprimindo \nliteralmente quando queria imprimir um caractere de nova linha.
Paul Paulo
@Paulpro não é '\ n' o novo caractere de linha?
Alexander Mills
3
@AlexMills É a sequência de escape para um caractere de nova linha, mas não é um caractere de nova linha. Eu estava recebendo um n literal ` followed by an , quando queria gerar um caractere de nova linha real.
Paul
378

Além disso, se você quiser sobrescrever mensagens na mesma linha, por exemplo, em uma contagem regressiva, poderá adicionar '\ r' no final da string.

process.stdout.write("Downloading " + data.length + " bytes\r");
defvol
fonte
18
Embora não seja a resposta para a pergunta, esta é uma resposta incrível. Mal posso esperar para tentar.
Longda
8
Isso não funciona no Windows para mim. Mas funciona muito bem em não-dows.
#
45
Para Windows, você pode usar o código equivalente '\ 033 [0G', como em:process.stdout.write("Downloading " + data.length + " bytes\033[0G");
GarciadelCastillo
19
Para fazer o código de escape ansi dado acima em um comentário por @GarciadelCastillo ao trabalho no modo estrito, substitua o octal literal \033com o literal hex \x1bassim: \x1b[0G. (que funciona tanto com código rigorosa e não-estrito)
alguns
7
Basta colocar o \ r no início e não no final da string para fazê-lo funcionar no Windows.
21416 daremkd
20

No console do Windows (Linux também), você deve substituir '\r'por seu código equivalente \033[0G:

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

Isso usa uma sequência de escape do terminal VT220 para enviar o cursor para a primeira coluna.

Yan Te
fonte
1
Como você retornaria várias linhas em vez da linha atual? O programa superior parece ser capaz de substituir todo o meu buffer enquanto ele está sendo executado e restaura o que estava lá quando foi concluído. Alguém sabe como isso faz? i.imgur.com/AtCmEjn.gif
Chev
Eu acredito que provavelmente usa algo parecido com um destes: github.com/mscdex/node-ncurses github.com/chjj/blessed
Brandon
1
Funciona, mas eu entendo o cursor [\] 39e o cursor é destacado no primeiro caracter:var spinner = '|/-\\'.split('');process.stdout.write("["+this.randomElement(spinner)+"] "+message+"\033[0G");
loretoparisi
1
O @Chev Top é especial, não é algo que você pode escrever com códigos de escape ANSI. Ele, de fato, usar ncurses é por isso que você não vai encontrá-lo em sistemas embarcados que não têm grandes bibliotecas C
cat
1
@ Chev: A maioria das pessoas o dissuadirá de jogar com seqüências de escape codificadas devido ao seu próprio FUD, mas quase todo mundo usa o VT100 agora, então a compatibilidade não é mais um problema. A funcionalidade a que você está se referindo é o comportamento de "tela alternativa". Uma introdução básica pode ser encontrada em man console_codes(no Linux ou online) e minha referência favorita é www2.phys.canterbury.ac.nz/dept/docs/manuals/unix/DEC_4.0e_Docs/… (99% de seu conteúdo ainda funciona) . Apenas ressalva: esteja preparado para testar qualquer experimento em vários terminais diferentes antes de implantar amplamente.
I336_
18

Como uma expansão / aprimoramento da brilhante adição feita por @rodowi acima em relação à possibilidade de substituir uma linha:

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

Se você não deseja que o cursor do terminal esteja localizado no primeiro caractere, como vi no meu código, considere o seguinte:

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)

Colocando-o \rna frente da próxima instrução de impressão, o cursor é redefinido antes que a sequência de substituição substitua a anterior.

mraxus
fonte
13

util.print também pode ser usado. Leia: http://nodejs.org/api/util.html#util_util_print

util.print ([...]) # Uma função de saída síncrona. Bloqueará o processo, converterá cada argumento em uma string e depois produzirá stdout. Não coloca novas linhas após cada argumento.

Um exemplo:

// 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
fonte
39
util.printestá obsoleto agora
Petr Peller
(node:7616) DeprecationWarning: util.print is deprecated. Use console.log instead.
Green
10

Parece haver muitas respostas sugerindo:

process.stdout.write

Os logs de erro devem ser emitidos em:

process.stderr

Em vez disso, use:

console.error

Para quem se pergunta por que process.stdout.write('\033[0G');não estava fazendo nada, é porque stdoutestá armazenado em buffer e você precisa aguardar o drainevento ( mais informações ).

Se a gravação retornar, falseela disparará um drainevento.

Ahmed Masud
fonte
4

Nenhuma dessas soluções funciona para mim, process.stdout.write('ok\033[0G')e apenas usando '\r'apenas crie uma nova linha, mas não a substitua no Mac OSX 10.9.2.

EDIT: Eu tive que usar isso para substituir a linha atual:

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

Eu recebi o seguinte erro ao usar o modo estrito:

Erro do nó: "Literais octais não são permitidos no modo estrito".

A seguinte solução funciona ( fonte ):

process.stdout.write("received: " + bytesReceived + "\x1B[0G");
blablabla
fonte
Altere o formato numérico literal ocltal tobsone.orher
FrancescoMM