Node.js: печатать на консоль без завершающей строки?


683

Есть ли способ печати на консоль без завершающей строки? consoleОбъект документации ничего не говорит о том , что:

console.log()

Печать на стандартный вывод с новой строки. Эта функция может принимать несколько аргументов printf()аналогично. Пример:

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

Если форматирующие элементы не найдены в первой строке, то util.inspectиспользуется для каждого аргумента.

Ответы:


1058

Вы можете использовать process.stdout.write():

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

Смотрите документы для деталей .


7
Это решило противоположную проблему для меня. console.logпечатал \nбуквально, когда я хотел напечатать символ новой строки.
Paul

@Paulpro не '\ n' символ новой строки?
Александр Миллс

3
@AlexMills Это escape-последовательность для символа новой строки, но это не сам символ новой строки. Я получал буквальный ` followed by an n`, когда я хотел вывести реальный символ новой строки.
Пол

379

Кроме того, если вы хотите перезаписать сообщения в той же строке, например, в обратном отсчете, вы можете добавить '\ r' в конце строки.

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

18
Хотя это и не ответ на вопрос, это удивительный ответ. Не могу дождаться, чтобы попробовать.
Longda

8
Это не работает на Windows для меня. Но отлично работает на не Доу.
Чоуи

45
Для Windows вы можете использовать эквивалентный код '\ 033 [0G', например:process.stdout.write("Downloading " + data.length + " bytes\033[0G");
GarciadelCastillo

19
Для того, чтобы AnSi кода побега приведенного выше в комментариях по @GarciadelCastillo на работу в строгом режиме, замените восьмеричный литерал \033с шестигранным литералом , \x1bкак это: \x1b[0G. (это работает как со строгим, так и со строгим кодом)
около

7
Просто поместите \ r в начале, а не в конце строки, чтобы она работала в Windows.
daremkd

20

В консоли Windows (в том числе и в Linux) вы должны заменить '\r'ее эквивалентным кодом \033[0G:

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

При этом используется escape-последовательность терминала VT220 для отправки курсора в первый столбец.


1
Как бы вы вернулись на несколько строк вместо текущей? Верхняя программа , кажется , чтобы иметь возможность перекрыть весь мой буфер , пока он работает и восстанавливает то , что было там , когда это сделано. Кто-нибудь знает, как это происходит? i.imgur.com/AtCmEjn.gif
Chev

Я полагаю, что он, вероятно, использует что-то вроде одного из них: github.com/mscdex/node-ncurses github.com/chjj/blessed
Брэндон

1
Это работает, но я также получаю курсор, [\] 39и курсор выделяется на первом var spinner = '|/-\\'.split('');process.stdout.write("["+this.randomElement(spinner)+"] "+message+"\033[0G");
символе

1
@Chev Top - это нечто особенное, его нельзя написать с помощью управляющих кодов ANSI. Он действительно использует ncurses, поэтому вы не найдете его во встроенных системах, в которых нет больших библиотек C
cat

1
@Chev: Большинство людей отговаривают вас играть с жестко запрограммированными escape-последовательностями из-за их собственного FUD, но почти каждый сейчас использует VT100, поэтому совместимость больше не является проблемой. Функциональность, на которую вы ссылаетесь - это поведение «альтернативного экрана». Базовое введение можно найти в man console_codes(на Linux или в Интернете), и моя любимая ссылка - www2.phys.canterbury.ac.nz/dept/docs/manuals/unix/DEC_4.0e_Docs/… (99% его содержимого все еще работают) , Только предостережение: будьте готовы проверить любые эксперименты на нескольких разных терминалах, прежде чем развернуть их широко.
i336_

18

В качестве расширения / улучшения блестящего дополнения, сделанного @rodowi выше относительно возможности перезаписи строки:

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

Если вы не хотите, чтобы курсор терминала находился на первом символе, как я видел в своем коде, рассмотрите возможность сделать следующее:

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)

Помещая \rперед следующим оператором печати, курсор сбрасывается непосредственно перед тем, как замещающая строка перезаписывает предыдущую.


13

Можно также использовать util.print . Читайте: http://nodejs.org/api/util.html#util_util_print

util.print ([...]) # Функция синхронного вывода. Блокирует процесс, приводит каждый аргумент к строке, а затем выводит на стандартный вывод. Не ставит новые строки после каждого аргумента.

Пример:

// 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.printустарела
Петр Пеллер

(node:7616) DeprecationWarning: util.print is deprecated. Use console.log instead.
Зеленый

10

Там, кажется, есть много ответов, предлагающих:

process.stdout.write

Журналы ошибок должны отправляться:

process.stderr

Вместо этого используйте:

console.error

Для тех, кто интересуется, почему process.stdout.write('\033[0G');ничего не делал, это потому, что stdoutон буферизован, и вам нужно ждать drainсобытия ( подробнее ).

Если запись возвращается false это вызовет drainсобытие.


5

Ни одно из этих решений не работает для меня, process.stdout.write('ok\033[0G')и просто с помощью'\r' новую строку, но не перезаписываю на Mac OSX 10.9.2.

РЕДАКТИРОВАТЬ: я должен был использовать это, чтобы заменить текущую строку:

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

4

Я получил следующую ошибку при использовании строгого режима:

Ошибка узла: «Октальные литералы не допускаются в строгом режиме».

Следующее решение работает ( источник ):

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

Измените числовой формат ocltal tobsone.orher
FrancescoMM
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.