如何在控制台上更新多行数据

8

我希望在控制台上显示两行数据。我只想每次更新这两行。

到目前为止,我所做的是 -

var _logInline = function(alpha, bravo) {
    process.stdout.cursorTo(0, 0);
    process.stdout.clearLine();
    process.stdout.cursorTo(0);
    process.stdout.write(alpha.toString());
    process.stdout.write('\n');
    process.stdout.clearLine();
    process.stdout.cursorTo(0);
    process.stdout.write(bravo.toString());
    process.stdout.write('\n');

};

var delay = 1000;
var time = 0;
setInterval(function() {
    time++;
    _logInline('alpha-' + time, 'bravo-' + time * time);
}, delay);

这种解决方案的明显问题是,光标会跑到窗口顶部。我不想要那样,相反,它应该在光标所在位置显示内容。可能需要先获取逻辑中的当前光标位置。有没有一种方法可以做到这一点?
替代方案并且最优选的方案是获取一个能够执行同样任务的库。
编辑:我在stackoverflow上看到了一些问题,它们提供了在没有换行符的情况下记录日志的选项,但这不完全是我想要的。我想要多个无换行符的记录。

你可以在Bash中获取光标位置(请参见此代码片段),但在Windows中无法工作。 我找到的最简单的解决方案是:http://pastebin.com/y69by2QE(但使用 cursorTo(0, 0))。 - Fabien Sa
2个回答

1

ncurses是我用过的最强大的库,可用于控制终端。mscdex提供了一个出色的npm包,可以绑定到c库https://npmjs.org/package/ncurses

但是,对于您的需求来说可能有些过度,这里有一种替代方案,但需要使用bash脚本:

基于this gist,我编写了以下代码,适应您的示例,您可以从gist中下载它或在此处阅读它,请不要忘记使用以下命令为bash脚本添加执行权限:

  chmod +x cursor-position.sh 

cursor-position.js

module.exports = function(callback) {
  require('child_process').exec('./cursor-position.sh', function(error, stdout, stderr){
    callback(error, JSON.parse(stdout));
  });
}

cursor-position.sh

#!/bin/bash
# based on a script from http://invisible-island.net/xterm/xterm.faq.html
# https://dev59.com/-XE85IYBdhLWcg3w3Xdp
exec < /dev/tty
oldstty=$(stty -g)
stty raw -echo min 0
# on my system, the following line can be replaced by the line below it
echo -en "\033[6n" > /dev/tty
# tput u7 > /dev/tty    # when TERM=xterm (and relatives)
IFS=';' read -r -d R -a pos
stty $oldstty
# change from one-based to zero based so they work with: tput cup $row $col
row=$((${pos[0]:2} - 1))    # strip off the esc-[
col=$((${pos[1]} - 1))
echo \{\"row\":$row,\"column\":$col\}

index.js

var getCursorPosition = require('./cursor-position');

var _logInline = function(row, msg) {
  if(row >= 0) row --; //litle correction
  process.stdout.cursorTo(0, row);
  process.stdout.clearLine();
  process.stdout.cursorTo(0, row);
  process.stdout.write(msg.toString());
};

var delay = 1000;
var time = 0;

//Start by getting the current position
getCursorPosition(function(error, init) {
  setInterval(function() {
      time++;
      _logInline(init.row, 'alpha-' + time);
      _logInline(init.row + 1, 'bravo-' + time * time);
  }, delay);
});

gist示例的链接已损坏。 - TacB0sS

0

我已经考虑了很长时间要做这件事。

这是一个非常天真的多行解决方案:


import {execSync} from "child_process";

var util = require('util');
var x = 0;
var y = 100;
setInterval(function () {
    execSync('tput cuu1 tput el tput cuu1 tput el', {stdio: 'inherit'});
    process.stdout.write(`hello1: ${x++}\nhello2: ${y++}\r`);  // needs return '/r'
    // util.print('hello: ' + x + '\r');  // could use this too
}, 1000);

我会在有更健壮的实现时进行更新。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接