Hitung jumlah garis keluaran dari program sebelumnya


32

Saya mencoba menghitung jumlah garis keluaran yang dihasilkan oleh program tertentu. Masalahnya adalah, program ini membutuhkan waktu lama untuk dijalankan, dan saya ingin menampilkan output kepada pengguna. Apakah ada cara untuk menghitung jumlah baris yang dihasilkan perintah terakhir?

Saya bisa melakukan program | wc -ltetapi itu tidak akan menampilkan output kepada pengguna. Jadi sejauh yang saya tahu, saya harus melakukan program; program | wc -l- tetapi program ini membutuhkan setidaknya satu menit untuk berjalan, jadi saya tidak ingin harus melakukannya lebih dari sekali hanya untuk menunjukkan jumlah baris di bagian bawah.

EDIT:

  • Apakah ada cara untuk menunjukkan output saat terjadi (baris demi baris) dan kemudian mengembalikan hitungan di akhir?

Bagaimana dengan: memiliki program melacak output sendiri dan hanya membaca nilai itu dari variabel (misalnya STDOUT_WRITE_COUNT), atau login ke file / API, di akhir program. WDYT?
mecampbellsoup

Jawaban:


43

Anda dapat menggunakan teeuntuk membagi aliran output mengirim satu salinan ke wcdan salinan lainnya ke STDOUT seperti biasa.

program | tee >(wc -l)

The >(cmd)sintaks pesta yang berarti menjalankan cmddan mengganti >(cmd)bit dengan path ke (pipa bernama terhubung ke) bahwa program STDIN.


2
>(cmd)adalah kshsintaks yang juga dikenali oleh zshdan bashdan hanya menggunakan pipa bernama pada sistem yang tidak memiliki /dev/fd/n.
Stéphane Chazelas

@StephaneChazelas Ya, sebagian besar shell mendukungnya, tetapi tidak pada POSIX, jadi tidak dapat diandalkan untuk berada di mana-mana.
Patrick

Ya, saya baru saja menunjukkan bahwa proses substitusi bukanlah bashpenemuan karena kata-kata dalam jawaban Anda dapat membuat orang percaya.
Stéphane Chazelas

1
@TheLibbster Tergantung pada bagaimana Anda mendefinisikan efisien. Metode ini memang melibatkan pemijahan 2 proses tambahan, dimana as seddan awkhanya satu. Tapi teedan wckeduanya sangat kecil (jauh lebih kecil dari seddan awk).
Patrick

1
@ TheLibbster ya, menurut beberapa tes sederhana yang baru saja saya lakukan, sebenarnya sekitar dua kali lebih cepat dari kedua metode seddan awk. (Saya ddd 100mb /dev/urandomke file dan kemudian menjalankan file itu melalui setiap metode beberapa kali)
Patrick

10

Salah satu opsi adalah menggunakan awk, yang dapat melakukan penghitungan dan mencetak ke stdout.

program | awk '{ print } END { print NR }'

Dalam awk, NR adalah nomor baris saat ini. Anda dapat mencapai hal yang sama dengan perl:

program | perl -pe 'END {print "$.\n"}'

Atau sed:

program | sed -n 'p;$='

Apakah ada cara untuk menunjukkan output saat terjadi (baris demi baris) dan kemudian mengembalikan hitungan di akhir?
Libbux

6

Anda dapat mengkloning stdout di stderr.

program | tee /dev/stderr | wc -l

Dengan begitu, programstdout disalurkan ketee ditulis ke stderr, yang dicetak pada konsol. teejuga menulis data yang disalurkan ke stdout, yang disalurkan ke wc.


3

opsi favorit saya:

program | grep "" -c

1
OP mungkin bertanya sesuatu yang lain, tetapi saya datang ke sini hanya mencari hitungan jumlah output baris dan tidak peduli untuk menunjukkan output aktual, dan ini berhasil. Terima kasih!
Nikhil VJ

0
tail -f /var/log/squid/access.log | ( c=0; pl() { echo $c; c=0; }; trap pl SIGHUP; while read a; do (( c=c+1 )); done ) & ( trap 'kill $! ; exit' SIGINT; trap '' SIGHUP; while true; do kill -HUP $! ; sleep 1; done)

0

Ini mungkin terlambat. Tapi saya hanya akan menjawab pertanyaan tindak lanjut Anda tentang cara untuk menangkap nomor yang dihitung dalam suatu variabel.

Ini yang kamu inginkan YOUR_VAR=$(PROGRAM | tee /dev/stderr | wc -l).

Kami mengambil keuntungan dari teemenghasilkan dua aliran di sini dan mengarahkan satu ke /dev/stderr, yang akan muncul di layar Anda, dan yang lainnya ke wc -l, yang akan melaporkan jumlah baris.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.