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
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)tokshskładnia również rozpoznawana przezzshibashi 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
bashjako 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
sediawkto tylko jeden. Aleteeiwcsą bardzo małe (znacznie mniejsze niżsediawk). - @TheLibbster tak, zgodnie z kilkoma prostymi testami, które właśnie przeprowadziłem, ' jest prawie dwa razy szybszy jako metody
sediawk. (Iddd 100 MB z/dev/urandomdo 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)
STDOUT_WRITE_COUNT) lub zaloguj się do pliku / interfejsu API na końcu programu. WDYT?