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

683

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

console.log()

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

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

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

Эван Кэрролл
источник

Ответы:

1058

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

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

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

onteria_
источник
7
Это решило противоположную проблему для меня. console.logпечатал \nбуквально, когда я хотел напечатать символ новой строки.
Paul
@Paulpro не '\ n' символ новой строки?
Александр Миллс
3
@AlexMills Это escape-последовательность для символа новой строки, но это не сам символ новой строки. Я получал буквальный ` followed by an n`, когда я хотел вывести реальный символ новой строки.
Пол
379

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

process.stdout.write("Downloading " + data.length + " bytes\r");
defvol
источник
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перед следующим оператором печати, курсор сбрасывается непосредственно перед тем, как замещающая строка перезаписывает предыдущую.

mraxus
источник
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");
});
douyw
источник
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');
Tyguy7
источник
4

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

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

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

process.stdout.write("received: " + bytesReceived + "\x1B[0G");
блаблабла
источник
Измените числовой формат ocltal tobsone.orher
FrancescoMM