Încerc să număr numărul de linii de ieșire pe care le produce un anumit program. Problema este că programul durează mult timp pentru a rula și vreau să afișez ieșirea către utilizator. Există o modalitate de a număra numărul de linii pe care a ieșit ultima comandă?
Aș putea face program | wc -l
, dar asta nu ar arăta ieșirea către utilizator. Deci, din câte știu, trebuie să fac program; program | wc -l
– dar programul durează cel puțin un minut pentru a rula, așa că nu vreau să trebuiască să o fac mai mult decât o dată pentru a afișa un număr de linii în partea de jos.
EDIT:
- Există o modalitate de a arăta ieșirea așa cum se întâmplă (linie cu linie) și apoi de a returna un număr la sfârșit?
Comentarii
Răspuns
Puteți utiliza tee
pentru a împărți fluxul de ieșire trimitând o copie către wc
și cealaltă copie în STDOUT ca în mod normal.
program | tee >(wc -l)
>(cmd)
este sintaxă bash care înseamnă ru n cmd
și înlocuiți bitul >(cmd)
cu calea către (o conductă numită conectată la) acel program STDIN.
Comentarii
-
>(cmd)
esteksh
sintaxă recunoscută și dezsh
șibash
și folosește numai țevi numite pe sisteme care nu au ' t are/dev/fd/n
. - @StephaneChazelas Da, majoritatea shell-urilor îl acceptă, dar ' nu se află în POSIX, deci nu se poate ' să se bazeze pe el pentru a fi pretutindeni.
- Da, tocmai am subliniat că substituirea procesului nu era un
bash
invenție, deoarece formularea din răspunsul dvs. ar putea lăsa pe cineva să creadă. - @TheLibbster Depinde de modul în care definiți eficient. Această metodă implică apariția a două procese suplimentare, în care
sed
șiawk
sunt doar unul. Dartee
șiwc
sunt ambele extrem de mici (mult mai mici decâtsed
șiawk
). - @TheLibbster da, conform unor teste simple pe care tocmai le-am făcut, ' este de fapt de aproximativ două ori mai rapid ca atât metodele
sed
, cât șiawk
. (Amdd
d 100mb din/dev/urandom
într-un fișier și apoi am rulat acel fișier prin fiecare metodă de mai multe ori)
Răspuns
O opțiune este să utilizați awk, care poate efectua numărarea și imprima pe stdout.
program | awk "{ print } END { print NR }"
În awk
, NR este numărul curent al liniei. Puteți realiza același lucru cu perl:
program | perl -pe "END {print "$.\n"}"
Sau sed
:
program | sed -n "p;$="
Comentarii
- Există o modalitate de a arăta ieșirea așa cum se întâmplă (linie cu linie) și apoi de a returna un număr la sfârșit ?
Răspunde
opțiunea mea preferată:
program | grep "" -c
Comentarii
- Poate că OP a cerut altceva, dar am venit aici căutând doar un număr de linii de ieșire și nu ' nu-i pasă de afișarea rezultatului real, iar acest lucru face treaba. Mulțumim!
Răspuns
Puteți clona stdout pe stderr.
program | tee /dev/stderr | wc -l
În acest fel, stdout-ul program
” este canalizat către tee
pentru a fi scris în stderr, care este tipărit pe consolă. tee
scrie, de asemenea, datele canalizate către acesta în stdout-ul său, care este canalizat către wc
.
Răspuns
S-ar putea să întârzie. Dar aș aborda întrebarea dvs. de urmărire cu privire la modul de a prinde numărul numărat într-o variabilă.
Asta vrei YOUR_VAR=$(PROGRAM | tee /dev/stderr | wc -l)
.
Profităm de tee
generând două fluxuri aici și direcționați unul către /dev/stderr
, care va apărea pe ecranul dvs., iar celălalt către wc -l
, care ar raporta numărul de linii.
Răspuns
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
), sau conectați-l la un fișier / API, la sfârșitul programului. WDYT?