Policz liczbę wierszy wyniku poprzedniego programu

Próbuję policzyć liczbę wierszy danych wyjściowych, które generuje dany program. Problem polega na tym, że program wykonanie zajmuje dużo czasu i chcę wyświetlić dane wyjściowe użytkownikowi. Czy istnieje sposób, aby policzyć liczbę wierszy wyświetlanych przez ostatnie polecenie?

Mógłbym zrobić program | wc -l, ale to nie pokazałoby danych wyjściowych użytkownikowi. O ile mi wiadomo, muszę zrobić program; program | wc -l – ale program działa co najmniej minutę, więc nie chcę robić tego więcej niż raz aby wyświetlić liczbę wierszy u dołu.

EDYCJA:

  • Czy istnieje sposób na pokazanie wyniku na bieżąco (wiersz po wierszu), a następnie zwrócenie liczby na końcu?

Komentarze

  • Co powiesz na to: niech program śledzi własne dane wyjściowe i po prostu odczyta tę wartość ze zmiennej (np. STDOUT_WRITE_COUNT) lub zaloguj się do pliku / interfejsu API na końcu programu. WDYT?

Odpowiedź

Możesz użyć tee, aby podzielić strumień wyjściowy, wysyłając jedną kopię do wc i druga kopia do STDOUT jak normalnie.

program | tee >(wc -l) 

>(cmd) to składnia basha, co oznacza ru n cmd i zastąp bit >(cmd) ścieżką do (połączonego potoku nazwanego) STDIN tego programu.

Komentarze

  • >(cmd) to ksh składnia również rozpoznawana przez zsh i bash i używa tylko nazwanych potoków w systemach, które nie ' t mają /dev/fd/n.
  • @StephaneChazelas Tak, większość powłok to obsługuje, ale ' nie ma POSIX, więc nie można polegać na ', że będzie wszędzie.
  • Tak, właśnie wskazałem, że podstawienie procesu nie było bash jako sformułowanie w Twojej odpowiedzi może pozwolić uwierzyć.
  • @TheLibbster Zależy od tego, jak zdefiniujesz efektywność. Ta metoda wymaga tworzenia 2 dodatkowych procesów, gdzie jako sed i awk to tylko jeden. Ale tee i wc są bardzo małe (znacznie mniejsze niż sed i awk).
  • @TheLibbster tak, zgodnie z kilkoma prostymi testami, które właśnie przeprowadziłem, ' jest prawie dwa razy szybszy jako metody sed i awk. (I dd d 100 MB z /dev/urandom do pliku, a następnie kilkakrotnie uruchomiłem ten plik każdą metodą)

Odpowiedź

Jedną z opcji jest użycie awk, który może zliczać i drukować na standardowe wyjście.

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

W awk NR to bieżący numer linii. Możesz zrobić to samo z perlem:

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

Lub sed:

program | sed -n "p;$=" 

Komentarze

  • Czy istnieje sposób pokazania wyniku, gdy to się dzieje (wiersz po wierszu), a następnie zwrócenia liczby na końcu ?

Odpowiedz

moja ulubiona opcja:

program | grep "" -c 

Komentarze

  • OP mógł zapytać o coś innego, ale przyszedłem tutaj, szukając po prostu liczby wyświetlanych wierszy i nie ' Nie przejmuję się wyświetlaniem rzeczywistych wyników, a to załatwia sprawę. Dzięki!

Odpowiedź

Możesz sklonować standardowe wyjście na stderr.

program | tee /dev/stderr | wc -l 

W ten sposób program” standardowe wyjście jest przesyłane potokiem do tee w celu zapisania na stderr, czyli wydrukowane na konsoli. tee również zapisuje dane przesyłane do niego potokiem na swoje standardowe wyjście, które jest przesyłane potokiem do wc.

Odpowiedź

To może być późno. Chciałbym jednak odpowiedzieć na Twoje dodatkowe pytanie, jak złapać policzoną liczbę w zmiennej.

Właśnie tego chcesz YOUR_VAR=$(PROGRAM | tee /dev/stderr | wc -l).

Korzystamy z tee generowania tutaj dwóch strumieni i skieruj jedną do /dev/stderr, która pojawiłaby się na ekranie, a drugą do wc -l, która będzie raportować liczbę wierszy.

Odpowiedź

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) 

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *