Làm cách nào để hiển thị số lượng dòng đầu ra bằng một lệnh trong thời gian thực?


15

Tôi đang sử dụng svn exportnhư một phần của tập lệnh đóng gói cho ứng dụng của mình và có vẻ như lệnh này, giống như nhiều lệnh khác, không có bất kỳ loại thanh tiến trình nào.

Tôi có hai lựa chọn vào lúc này:

  • sử dụng nó mà không có tùy chọn, và xem nó in hàng ngàn dòng
  • sử dụng --quiet, và không thu giữ bất cứ thứ gì cho đến khi hoàn thành.

Có cách nào để hiển thị số lượng dòng đầu ra của lệnh theo thời gian thực không? Nhu la:

Exporting SVN directory ... 1234 files

Và xem con số này 1234 tăng lên trong thời gian thực ? Tôi có thể tưởng tượng đường ống đầu ra đến một lệnh sẽ làm điều này, nhưng cái nào?

Câu trả lời:


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

Hoặc đặt phần ngoặc trong một kịch bản shell. Lưu ý rằng điều này chỉ hoạt động nếu shell của bạn thực sự hỗ trợ toán tử preincrement, như bash hoặc ksh93 hoặc zsh. Nếu không, bạn sẽ phải tăng lên $Ivà sau đó in nó (như trong I=$((I+1));printf...). Ngoài ra, nếu printfkhông phải là nội trang với vỏ của bạn (đó là nội dung tích hợp với bash hiện tại), bạn có thể sử dụng echo -nehoặc print -nthay vào đó để có hiệu suất tốt hơn. Bạn chỉ muốn chặn dòng mới và \ \ được hiểu là một ký tự thoát.


Ồ, tôi sẽ không bao giờ khiến bản thân mình học bashscripting với tất cả sự =khác biệt xấu xí và `=`. :) Tại sao họ không thay thế nó bằng ngôn ngữ giống như con trăn ...
Boris Burkov

Này, tôi biết, cái gì! Bạn có thể thêm biểu tượng hoàn trả vận chuyển cho mỗi dòng mới bạn in và nó sẽ không tràn vào màn hình, nó sẽ chỉ ghi đè lên dòng trước đó.
Boris Burkov

Đó là lý do tại sao printfkết thúc với một \r. Và điều gì xảy ra nếu bạn làm echo -ne "$I\r"hoặc print -n "$I\r". :) Tôi đã sử dụng printf, tuy nhiên, vì nó mặc định không in một dòng mới ở cuối, vì vậy \rchỉ cần di chuyển trở lại từ đầu. Không phải tất cả các triển khai echo đều hỗ trợ -ehoặc -nđối số, không may.
dannysauer

1
Điều này cũng hoạt động với phiên bản pdksh mà OpenBSD sử dụng cho / bin / sh.
kurtm

1
+1, mặc dù là hoàn toàn chính xác, bạn nên đổi readthành read -r(vì nếu không, dấu gạch chéo ngược ở cuối dòng sẽ gây rối với việc đếm). Ngẫu nhiên, với một chút công việc, điều này có thể được điều chỉnh để hiển thị dòng đầu ra mới nhất, có thể hữu ích cho một số lệnh.
ruakh

7

Đây là một ý tưởng sơ bộ nhưng bạn có thể sử dụng pvlệnh để đếm số lượng dòng khi chúng đi qua và hiển thị nó trên màn hình. pvtrong số đó có nhiều công tắc có một -lcông tắc đếm từng dòng khi nó đi qua.

Thí dụ

Ở đây tôi đang sử dụng một vòng lặp while để mô phỏng một số tệp từ đầu ra SVN của bạn.

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

Nó sẽ tiếp tục ghi đè lên dòng đầu ra như thế này:

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

  24 0:00:47 [0.991/s ] [                                                <=>                                                      ]

Tôi đã không biết về pv. Hoan hô việc học!
dannysauer

@dannysauer - pv đáng để dành thời gian tìm hiểu, nó cho phép mọi thứ đi qua một đường ống được đo và hiển thị.
slm

Tôi đã cài đặt nó sau khi tôi đọc bình luận và đã chơi với nó. Mười tám năm sử dụng Linux, và vẫn luôn có những thứ mới để khám phá. :)
dannysauer

0

Bạn có thể chạy lệnh của bạn trong nền như một công việc và chuyển hướng thiết bị xuất chuẩn của nó (và tùy chọn stderr) sang logfile: command > logfile &nơi &chỉ định công việc (nếu stderr cũng vậy, nói &>thay vì >).

Sau đó, bạn có thể sử dụng tiện ích wordcount để đếm số lượng dòng trong logfile của bạn với wc -l.

Để hiển thị sự thay đổi trạng thái trong một dòng thay đổi linh hoạt, bạn có thể sử dụng một cái gì đó như while true; do echo -en '\r'; wc -l logfile; sleep 1; done, nhưng tôi không thể buộc bash để \rquay trở lại vận chuyển để giết nội dung của dòng trước đó.

Xem câu hỏi này, nó gần như là một bản sao: /programming/2388090/how-to-delete-and-replace-last-line-in-the-terminal-USE-bash


1
Nhưng anh ấy muốn một màn hình thời gian thực tiếp tục tăng, đó không phải là những gì wc làm.
kurtm

@kurtm eh, điều anh ấy muốn nhiều hơn nữa là đừng để màn hình của anh ấy tràn ngập kết quả printf/print/echonhư đề xuất của danny. :) Tất nhiên, anh ta có thể sử dụng less, nhưng tôi cho rằng, anh ta có thể đủ khả năng để nói wc -l logfilemọi lúc anh ta thiếu kiên nhẫn. Tôi nghĩ rằng, chơi với ncurseshoặc xóa màn hình là một việc quá mức ở đây.
Boris Burkov

Vâng, vâng. Anh ta không muốn nó bị ngập lụt, nhưng anh ta muốn biết tiến bộ, nếu không anh ta chỉ có thể sử dụng --quiet.
kurtm

@kurtm xem cập nhật: bạn có thể giúp gỡ lỗi echo -e 'r'lệnh của tôi không? Nó sẽ xóa các nội dung được in trước đó của dòng, để nó thay đổi linh hoạt, nhưng tôi không thể buộc nó làm điều đó :(
Boris Burkov

Bạn cũng muốn thêm tùy chọn n vào echo để loại bỏ dòng mới.
kurtm
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.