Node.js: друк на консолі без зворотного нового рядка?


683

Чи існує спосіб друку на консолі без зворотного нового рядка? consoleОб'єкт документації нічого не говорить про те , що:

console.log()

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

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

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

Відповіді:


1058

Ви можете використовувати process.stdout.write():

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

Докладніше див. У документах .


7
Це вирішило протилежну проблему для мене. console.logдрукував \nбуквально, коли я хотів, щоб він надрукував символ нового рядка.
Павло

@Paulpro - це не \ \ n 'таблиця нового рядка?
Олександр Міллс

3
@AlexMills Це послідовність вихідного символу для нового рядка, але це не сам символ нового рядка. Я отримував буквальний ` followed by an н`, коли хотів вивести справжній символ нового рядка.
Пол

379

Крім того, якщо ви хочете перезаписати повідомлення в одному рядку, наприклад, під час зворотного відліку, ви можете додати "\ r" в кінці рядка.

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

18
Хоча це не відповідь на питання, це чудова відповідь. Не можна чекати, щоб спробувати.
longda

8
Це не працює для Windows для мене. Але чудово працює на не-досів.
chowey

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

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

7
Просто покладіть \ r на початок, а не в кінець рядка, щоб він працював у Windows.
даремкд

20

У консолі Windows (також Linux) слід замінити '\r'її еквівалентним кодом \033[0G:

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

Для цього використовується послідовність відходу терміналу VT220 для надсилання курсору в перший стовпець.


1
Як би ви створили резервну копію декількох рядків замість лише поточної? Верхня програма , здається , щоб мати можливість перекрити весь мій буфер , поки він працює і відновлює те , що було там , коли це зроблено. Хтось знає, як це робиться? i.imgur.com/AtCmEjn.gif
Чев

Я вважаю, що, ймовірно, використовується щось подібне до цього: 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, саме тому ви не знайдете його у вбудованих системах, у яких немає великих ліфтів С
кішка

1
@Chev: Більшість людей відвернуть вас від гри з жорстко кодованими послідовностями втечі завдяки власному 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 ([...]) # Функція синхронного виводу. Блокує процес, передасть кожен аргумент у рядок, а потім виведе у stdout. Не розміщує нові рядки після кожного аргументу.

Приклад:

// 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події.


4

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

EDIT: Мені довелося використовувати це для заміни поточного рядка:

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

4

Я отримав таку помилку при використанні суворого режиму:

Помилка вузла: "Восьмі літерали не дозволені в суворому режимі."

Наступне рішення працює ( джерело ):

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

Змініть октальний буквальний tobsone.orher числовий формат
FrancescoMM
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.