ChatGPT解决这个技术问题 Extra ChatGPT

Node.js:在没有尾随换行符的情况下打印到控制台?

有没有一种在没有尾随换行符的情况下打印到控制台的方法? console 对象 documentation 没有说明任何相关内容:

console.log() 使用换行符打印到标准输出。此函数可以以类似 printf() 的方式接受多个参数。示例:console.log('count: %d', count);如果在第一个字符串中未找到格式化元素,则在每个参数上使用 util.inspect。


A
Akseli Palén

您可以使用 process.stdout.write()

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

请参阅 docs for details


这为我解决了相反的问题。当我希望它打印换行符时,console.log 正在打印 \n
@Paulpro 不是 '\n' 换行符吗?
@AlexMills 这是换行符的转义序列,但它本身不是换行符。当我想输出一个真正的换行符时,我得到了一个文字 ` followed by an n`。
天才。不知道你能做到这一点。
在 Node.js 上打印 hello: true
Y
Yoav Kadosh

此外,如果您想覆盖同一行中的消息,例如在倒计时中,您可以在字符串末尾添加 \r

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

虽然不是问题的答案,但这是一个惊人的答案。迫不及待想试试。
这对我来说在 Windows 上不起作用。但在非道琼斯指数上效果很好。
对于 Windows,您可以使用等效代码“\033[0G”,如:process.stdout.write("Downloading " + data.length + " bytes\033[0G");
要使上述@GarciadelCastillo 在评论中给出的 ansi escape code 在严格模式下工作,请将八进制文字 \033 替换为十六进制文字 \x1b,如下所示:\x1b[0G。 (适用于严格和非严格代码)
只需将 \r 放在字符串的开头而不是结尾即可使其在 Windows 中工作。
m
mraxus

作为对@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 放在下一个打印语句的前面,光标在替换字符串覆盖前一个之前被重置。


L
LogicalBranch

在 Windows 控制台(Linux 也是如此)中,您应该将 '\r' 替换为其等效代码 \033[0G

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

这使用 VT220 终端转义序列将光标发送到第一列。


您将如何备份多行而不是仅返回当前行? top 程序似乎能够在运行时覆盖我的整个缓冲区,并在它完成后恢复那里的内容。有谁知道它是怎么做到的? i.imgur.com/AtCmEjn.gif
我相信它可能会使用以下其中一种:github.com/mscdex/node-ncurses github.com/chjj/blessed
它可以工作,但我得到的光标也像 [\] 39 一样,并且光标在第一个字符上突出显示:var spinner = '|/-\\'.split('');process.stdout.write("["+this.randomElement(spinner)+"] "+message+"\033[0G");
@Chev Top 很特别,不是你可以用 ANSI 转义码写的东西。它确实使用了 ncurses,这就是为什么在没有大型 C 库的嵌入式系统上找不到它的原因
@Chev:由于他们自己的 FUD,大多数人会劝阻您不要使用硬编码的转义序列,但是现在几乎每个人都使用 VT100,因此兼容性不再是真正的问题。您所指的功能是“交替屏幕”行为。可以在 man console_codes(在 Linux 上或在线)中找到基本介绍,我最喜欢的参考是 www2.phys.canterbury.ac.nz/dept/docs/manuals/unix/DEC_4.0e_Docs/…(其 99% 的内容仍然有效)。唯一需要注意的是:在广泛部署之前,请准备好在几个不同的终端上测试任何实验。
L
LogicalBranch

似乎有很多答案表明:

process.stdout.write

错误日志应在以下位置发出:

process.stderr

而是使用:

console.error

如果有人想知道为什么 process.stdout.write('\033[0G'); 没有做任何事情,那是因为 stdout 已缓冲,您需要等待 drain 事件 (more info)。

如果 write 返回 false,它将触发 drain 事件。


d
douyw

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

util.print 现已弃用
(node:7616) DeprecationWarning: util.print is deprecated. Use console.log instead.
TypeError: util.print is not a function
L
LogicalBranch

这些解决方案都不适合我,process.stdout.write('ok\033[0G') 并且仅使用 '\r' 只是创建一个新行,但不要在 Mac OSX 10.9.2 上覆盖。

编辑:我不得不用它来替换当前行:

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

L
LogicalBranch

使用严格模式时出现以下错误:

节点错误:“严格模式下不允许使用八进制文字。”

以下解决方案有效 (source):

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

更改八进制文字 tobsone.orher 数字格式
J
João Pimentel Ferreira

如果您希望它在 Linux 和 Windows、严格模式和非严格模式下都工作,并且每次打印时都完全清除该行,您可以使用

const str = 'Hi there'
process.stdout.write(str.padEnd(50) + '\x1b[0G')