Bagaimana cara menampilkan jumlah garis keluaran dengan perintah secara real time?

15

Saya menggunakan svn exportsebagai bagian dari skrip packager untuk aplikasi saya, dan sepertinya perintah ini, seperti banyak yang lainnya, tidak memiliki jenis progress bar.

Saya punya dua pilihan saat ini:

  • menggunakannya tanpa opsi, dan menontonnya mencetak ribuan baris
  • menggunakan --quiet, dan tidak melihat apa pun sampai selesai.

Apakah ada cara untuk setidaknya menunjukkan jumlah baris yang dihasilkan oleh perintah, secara real time? Seperti:

Exporting SVN directory ... 1234 files

Dan lihat 1234 peningkatan nomor ini secara real time ? Saya bisa membayangkan piping output ke perintah yang akan melakukan ini, tetapi yang mana?

Benjamin
sumber

Jawaban:

16
yourcommand | { I=0; while read; do printf "$((++I))\r"; done; echo ""; }

Atau letakkan bagian kurung di skrip shell. Perhatikan bahwa ini hanya berfungsi jika shell Anda benar-benar mendukung operator preincrement, seperti bash atau ksh93 atau zsh. Kalau tidak, Anda harus menambah $Ilalu mencetaknya (seperti pada I=$((I+1));printf...). Juga, jika printfbukan builtin dengan shell Anda (itu builtin dengan bash saat ini), Anda bisa menggunakan echo -neatau print -nsebagai gantinya untuk kinerja yang lebih baik. Anda hanya ingin menekan baris baru dan menafsirkannya sebagai karakter pelarian.

dannysauer
sumber
Oh, aku tidak akan pernah membuat diriku belajar bashscripting dengan semua =perbedaan dan quirks yang jelek dan `. :) Mengapa mereka tidak menggantinya dengan bahasa seperti-python-syntaxed ...
Boris Burkov
Hei, aku tahu, apa! Anda dapat menambahkan simbol carriage return ke setiap baris baru yang Anda cetak, dan itu tidak akan membanjiri layar, itu hanya akan menimpa baris sebelumnya.
Boris Burkov
Itu sebabnya printfberakhir dengan a \r. Dan apa yang terjadi jika Anda melakukannya echo -ne "$I\r"atau print -n "$I\r". :) Saya menggunakan printf, karena default untuk tidak mencetak baris baru di akhir, jadi \rhanya bergerak kembali ke awal. Sayangnya, tidak semua implementasi gema mendukung -eatau -nargumen.
dannysauer
1
Ini juga berfungsi dengan versi pdksh yang digunakan OpenBSD untuk / bin / sh.
kurtm
1
+1, meskipun harus sepenuhnya benar, Anda harus berubah readmenjadi read -r(karena jika tidak, garis miring terbalik pada akhir baris akan mengacaukan penghitungan). Kebetulan, dengan sedikit kerja, ini dapat disesuaikan untuk juga menunjukkan garis keluaran terbaru, yang mungkin berguna untuk beberapa perintah.
ruakh
7

Ini adalah ide kasar, tetapi Anda bisa menggunakan pvperintah untuk menghitung jumlah baris saat mereka lewat dan menampilkannya ke layar. pvdi antara itu banyak saklar memiliki -lsaklar yang menghitung setiap baris saat melewati.

Contoh

Di sini saya menggunakan loop sementara untuk mensimulasikan beberapa file dari output SVN Anda.

$ for i in $(seq 100); do echo "file$i"; sleep 2; done | pv -l -c >/dev/null
   3 0:00:05 [0.99/s ] [      <=>             

Ini akan terus menimpa jalur output seperti ini:

  18 0:00:36 [   0/s ] [                                     <=>                                                                  ]

  24 0:00:47 [0.991/s ] [                                                <=>                                                      ]
slm
sumber
Saya tidak menyadari pv. Hore untuk belajar hal-hal!
dannysauer
@dannysauer - pv layak menghabiskan waktu belajar, memungkinkan segala sesuatu yang melalui pipa dapat diukur dan ditampilkan.
slm
Saya menginstalnya setelah saya membaca komentar dan telah bermain dengannya. Delapan belas tahun menggunakan Linux, dan masih selalu ada hal baru untuk ditemukan. :)
dannysauer
0

Anda dapat menjalankan perintah di latar belakang sebagai pekerjaan dan mengarahkan stdout (dan stderr opsional) ke file log: di command > logfile &mana &menunjuk pekerjaan (jika stderr juga, katakan &>bukan >).

Kemudian Anda bisa menggunakan utilitas wordcount untuk menghitung jumlah baris dalam logfile Anda wc -l.

Untuk menampilkan perubahan status dalam satu baris yang berubah secara dinamis, Anda dapat menggunakan sesuatu seperti while true; do echo -en '\r'; wc -l logfile; sleep 1; done, tapi saya tidak bisa memaksa bash untuk menarik \rkereta kembali untuk membunuh konten dari baris sebelumnya.

Lihat pertanyaan ini, hampir merupakan duplikat: /programming/2388090/how-to-delete-and-replace-last-line-in-the-terminal-using-bash

Boris Burkov
sumber
1
Tapi dia ingin tampilan waktu nyata yang terus bertambah, yang bukan apa yang dilakukan wc.
kurtm
@kurtm eh, apa yang dia inginkan lebih banyak adalah tidak membuat layarnya dibanjiri dengan hasil printf/print/echoseperti yang disarankan oleh danny. :) Tentu saja, dia bisa menggunakan less, tapi saya kira, dia mampu mengatakan wc -l logfilesetiap kali dia tidak sabar. Saya pikir, bermain dengan ncursesatau membersihkan layar adalah hal yang berlebihan di sini.
Boris Burkov
Baiklah. Dia tidak ingin banjir, tetapi dia ingin tahu kemajuan, kalau tidak, dia bisa menggunakan --quiet.
kurtm
@kurtm lihat pembaruan: dapatkah Anda membantu men-debug echo -e 'r'perintah saya ? Seharusnya menghapus isi baris yang dicetak sebelumnya, sehingga secara dinamis berubah, tapi saya tidak bisa memaksanya untuk melakukan itu :(
Boris Burkov
Anda juga ingin menambahkan opsi n ke echo yang menekan baris baru yang tertinggal.
kurtm