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.

Respostas:


1056

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

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

Veja os documentos para obter detalhes .


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");

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.


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.


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");
});

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.


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');

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");

Altere o formato numérico literal ocltal tobsone.orher
— FrancescoMM
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.