Node.js: mencetak ke konsol tanpa baris baru yang tertinggal?

683

Apakah ada metode untuk mencetak ke konsol tanpa baris baru? The consoleobjek dokumentasi tidak mengatakan apa-apa tentang itu:

console.log()

Mencetak ke stdout dengan baris baru. Fungsi ini dapat mengambil beberapa argumen dengan printf()cara -seperti. Contoh:

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

Jika elemen formating tidak ditemukan dalam string pertama maka util.inspectdigunakan pada setiap argumen.

Evan Carroll
sumber

Jawaban:

1058

Anda bisa menggunakan process.stdout.write():

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

Lihat dokumen untuk detailnya .

onteria_
sumber
7
Ini memecahkan masalah yang berlawanan bagi saya. console.logsedang mencetak \nketika saya ingin mencetak karakter baris baru.
Paul
@Paulpro bukan '\ n' char baris baru?
Alexander Mills
3
@AlexMills Ini adalah urutan pelarian untuk karakter baris baru, tetapi itu bukan karakter baris baru itu sendiri. Saya mendapatkan ` followed by an n literal , ketika saya ingin menampilkan karakter baris baru yang sebenarnya.
Paul
379

Juga, jika Anda ingin menimpa pesan di baris yang sama, misalnya dalam hitungan mundur, Anda bisa menambahkan '\ r' di akhir string.

process.stdout.write("Downloading " + data.length + " bytes\r");
defvol
sumber
18
Meskipun bukan jawaban untuk pertanyaan, ini adalah jawaban yang luar biasa. Tidak sabar untuk mencoba.
longda
8
Ini tidak berfungsi pada Windows untuk saya. Tetapi bekerja dengan baik pada non-dow.
chowey
45
Untuk Windows, Anda dapat menggunakan kode setara '\ 033 [0G', seperti pada:process.stdout.write("Downloading " + data.length + " bytes\033[0G");
GarciadelCastillo
19
Untuk membuat kode escape ansi yang diberikan di atas dalam komentar oleh @GarciadelCastillo bekerja dalam mode ketat, menggantikan oktal literal \033dengan literal hex \x1bseperti ini: \x1b[0G. (yang bekerja dengan kode ketat dan non-ketat)
beberapa
7
Cukup letakkan di awal daripada di akhir string untuk membuatnya bekerja di Windows.
daremkd
20

Di konsol Windows (Linux juga), Anda harus mengganti '\r'dengan kode yang setara \033[0G:

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

Ini menggunakan urutan pelarian terminal VT220 untuk mengirim kursor ke kolom pertama.

Yan Te
sumber
1
Bagaimana Anda akan kembali beberapa baris, bukan hanya garis saat ini? Program teratas tampaknya dapat menimpa seluruh buffer saya saat sedang berjalan dan mengembalikan apa yang ada di sana ketika selesai. Adakah yang tahu bagaimana melakukan ini? i.imgur.com/AtCmEjn.gif
Chev
Saya percaya ini mungkin menggunakan sesuatu seperti ini: github.com/mscdex/node-ncurses github.com/chjj/blessed
Brandon
1
Ini bekerja tetapi saya mendapatkan kursor juga suka [\] 39dan kursor disorot pada karakter pertama:var spinner = '|/-\\'.split('');process.stdout.write("["+this.randomElement(spinner)+"] "+message+"\033[0G");
loretoparisi
1
@Chev Top adalah spesial, bukan sesuatu yang bisa Anda tulis dengan kode pelarian ANSI. Memang, memang, menggunakan ncurses yang mengapa Anda tidak akan menemukannya pada sistem embedded yang tidak memiliki lib C besar
cat
1
@Chev: Sebagian besar orang akan mencegah Anda bermain dengan urutan pelarian berkode keras karena FUD mereka sendiri, tetapi sekarang hampir semua orang menggunakan VT100, jadi kompatibilitas bukan lagi masalah. Fungsi yang Anda maksud adalah perilaku "layar alternatif". Intro dasar dapat ditemukan di man console_codes(di Linux atau online) dan referensi favorit saya adalah www2.phys.canterbury.ac.nz/dept/docs/manuals/unix/DEC_4.0e_Docs/… (99% dari kontennya masih berfungsi) . Hanya peringatan: Bersiaplah untuk menguji setiap percobaan pada beberapa terminal yang berbeda sebelum digunakan secara luas.
i336_
18

Sebagai perluasan / peningkatan pada penambahan brilian yang dibuat oleh @rodowi di atas tentang kemampuan untuk menimpa baris:

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

Jika Anda tidak ingin kursor terminal ditempatkan pada karakter pertama, seperti yang saya lihat dalam kode saya, pertimbangkan melakukan hal berikut:

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)

Dengan menempatkan bagian \rdepan pernyataan cetak berikutnya kursor akan diatur ulang tepat sebelum string pengganti menimpa yang sebelumnya.

Mraxus
sumber
13

util.print dapat digunakan juga. Baca: http://nodejs.org/api/util.html#util_util_print

util.print ([...]) # Fungsi output yang sinkron. Akan memblokir proses, melemparkan setiap argumen ke string kemudian output ke stdout Tidak menempatkan baris baru setelah setiap argumen.

Sebuah contoh:

// 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
sumber
39
util.printsudah ditinggalkan sekarang
Petr Peller
(node:7616) DeprecationWarning: util.print is deprecated. Use console.log instead.
Green
10

Tampaknya ada banyak jawaban yang menyarankan:

process.stdout.write

Log kesalahan harus dipancarkan pada:

process.stderr

Alih-alih gunakan:

console.error

Bagi siapa pun yang bertanya-tanya mengapa process.stdout.write('\033[0G');tidak melakukan apa-apa itu karena stdoutbuffered dan Anda perlu menunggu drainacara ( info lebih lanjut ).

Jika write return falseitu akan memunculkan suatu drainevent.

Ahmed Masud
sumber
4

Tidak satu pun dari solusi ini yang berfungsi untuk saya, process.stdout.write('ok\033[0G')dan hanya menggunakan '\r'cukup buat baris baru tetapi jangan menimpa pada Mac OSX 10.9.2.

EDIT: Saya harus menggunakan ini untuk mengganti baris saat ini:

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

Saya mendapat kesalahan berikut saat menggunakan mode ketat:

Kesalahan simpul: "Literal literal tidak diperbolehkan dalam mode ketat."

Solusi berikut berfungsi ( sumber ):

process.stdout.write("received: " + bytesReceived + "\x1B[0G");
blablabla
sumber
Ubah obstal literal menjadi. Format format numerik atau lainnya
FrancescoMM