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)
toksh
składnia również rozpoznawana przezzsh
ibash
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
iawk
to tylko jeden. Aletee
iwc
są bardzo małe (znacznie mniejsze niżsed
iawk
). - @TheLibbster tak, zgodnie z kilkoma prostymi testami, które właśnie przeprowadziłem, ' jest prawie dwa razy szybszy jako metody
sed
iawk
. (Idd
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)
STDOUT_WRITE_COUNT
) lub zaloguj się do pliku / interfejsu API na końcu programu. WDYT?