Numărați numărul de linii de ieșire din programul anterior

Î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

  • Ce zici: programul să țină evidența propriilor sale rezultate și să citească doar acea valoare din variabilă (de ex. STDOUT_WRITE_COUNT), sau conectați-l la un fișier / API, la sfârșitul programului. WDYT?

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) este ksh sintaxă recunoscută și de zsh și bash ș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 și awk sunt doar unul. Dar tee și wc sunt ambele extrem de mici (mult mai mici decât sed și awk).
  • @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 și awk. (Am dd 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) 

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *