Đếm số lượng dòng đầu ra từ chương trình trước


32

Tôi đang cố gắng đếm số lượng dòng đầu ra mà một chương trình nhất định tạo ra. Vấn đề là, chương trình mất nhiều thời gian để chạy và tôi muốn hiển thị đầu ra cho người dùng. Có cách nào để đếm số dòng lệnh xuất ra không?

Tôi có thể làm program | wc -lnhưng điều đó sẽ không hiển thị đầu ra cho người dùng. Theo như tôi biết, tôi phải làm program; program | wc -l- nhưng chương trình mất ít nhất một phút để chạy, vì vậy tôi không muốn phải làm nhiều hơn một lần chỉ để hiển thị số dòng ở phía dưới.

CHỈNH SỬA:

  • Có cách nào để hiển thị đầu ra khi nó xảy ra (từng dòng một) và sau đó trả lại một số đếm ở cuối?

Làm thế nào về: có chương trình theo dõi đầu ra của chính nó và chỉ cần đọc giá trị đó từ biến (ví dụ STDOUT_WRITE_COUNT), hoặc đăng nhập nó vào một tệp / API, ở cuối chương trình. WDYT?
mecampbellsoup

Câu trả lời:


43

Bạn có thể sử dụng teeđể phân chia luồng đầu ra gửi một bản sao đến wcvà bản sao khác tới STDOUT như bình thường.

program | tee >(wc -l)

Các >(cmd)là cú pháp bash mà phương tiện chạy cmdvà thay thế các >(cmd)bit với đường dẫn đến (một ống tên kết nối với) của chương trình mà STDIN.


2
>(cmd)kshcú pháp cũng được nhận ra bởi zshbashvà chỉ sử dụng các đường dẫn có tên trên các hệ thống không có /dev/fd/n.
Stéphane Chazelas

@StephaneChazelas Vâng, hầu hết các shell đều hỗ trợ nó, nhưng nó không có trong POSIX, vì vậy nó không thể dựa vào mọi nơi.
Patrick

Vâng, tôi chỉ chỉ ra rằng thay thế quá trình không phải là một bashphát minh vì từ ngữ trong câu trả lời của bạn có thể cho phép một người tin.
Stéphane Chazelas

1
@TheLibbster Phụ thuộc vào cách bạn xác định hiệu quả. Phương pháp này liên quan đến việc sinh ra 2 quá trình bổ sung, trong đó sedawkchỉ là một. Nhưng teewccả hai đều cực kỳ nhỏ (nhỏ hơn nhiều so với sedawk).
Patrick

1
@TheLibbster có, theo một số thử nghiệm đơn giản tôi vừa làm, nó thực sự nhanh gấp đôi cả phương pháp sedawkphương pháp. (Tôi gửi dd100mb /dev/urandomcho một tệp và sau đó chạy tệp đó qua từng phương thức vài lần)
Patrick

10

Một tùy chọn là sử dụng awk, có thể thực hiện đếm và in ra thiết bị xuất chuẩn.

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

Trong awk, NR là số dòng hiện tại. Bạn có thể thực hiện tương tự với perl:

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

Hoặc sed:

program | sed -n 'p;$='

Có cách nào để hiển thị đầu ra khi nó xảy ra (từng dòng một) và sau đó trả lại một số đếm ở cuối?
Libbux

6

Bạn có thể nhân bản stdout trên stderr.

program | tee /dev/stderr | wc -l

Theo cách đó, programthiết bị xuất chuẩn sẽ teeđược ghi vào thiết bị xuất chuẩn, được in trên bàn điều khiển. teecũng ghi dữ liệu được chuyển đến đầu ra của nó, được chuyển đến wc.


3

lựa chọn yêu thích của tôi:

program | grep "" -c

1
OP có thể đã hỏi một cái gì đó khác, nhưng tôi đến đây để tìm kiếm một số lượng đầu ra của dòng và không quan tâm đến việc hiển thị đầu ra thực tế, và điều này thực hiện công việc. Cảm ơn!
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

Điều này có thể là muộn. Nhưng tôi sẽ chỉ giải quyết câu hỏi tiếp theo của bạn về cách bắt số đếm trong một biến.

Đây là những gì bạn muốn YOUR_VAR=$(PROGRAM | tee /dev/stderr | wc -l).

Chúng tôi tận dụng việc teetạo hai luồng ở đây và hướng một luồng đến /dev/stderr, sẽ xuất hiện trên màn hình của bạn và luồng kia wc -lsẽ báo cáo số lượng dòng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.