Laske edellisen ohjelman tulostusrivien määrä

Yritän laskea tietyn ohjelman tuottamien rivien lukumäärän. Ongelmana on, että ohjelma kestää pitkään, ja haluan näyttää tuotoksen käyttäjälle. Onko mahdollista laskea viimeisen komennon annettujen rivien määrä?

Voisin tehdä program | wc -l, mutta se ei näytä tulosta käyttäjälle. Joten sikäli kuin tiedän, minun on tehtävä program; program | wc -l – mutta ohjelman suorittaminen vie vähintään minuutin, joten en halua, että minun on tehtävä se useammin kuin kerran vain näyttää rivimäärän alareunassa.

MUOKKAA:

  • Onko olemassa tapa näyttää ulostulo sen tapahtuessa (rivi riviltä) ja palauttaa sitten lukumäärä lopussa?

Kommentit

  • Entä: anna ohjelman seurata omaa lähtöään ja lukea vain arvo muuttujasta (esim. STDOUT_WRITE_COUNT) tai kirjaa se tiedostoon / sovellusliittymään ohjelman lopussa. WDYT?

Vastaa

Voit käyttää tee -toimintoa jakamaan ulostulovirran lähettämällä yhden kopion osoitteeseen wc ja toinen kopio STDOUT: iin tavalliseen tapaan.

program | tee >(wc -l) 

>(cmd) on bash-syntaksia, joka tarkoittaa ru n cmd ja korvaa bitti >(cmd) polulla ohjelman STDIN: ään (nimetty putki kytketty).

Kommentit

  • >(cmd) on ksh syntaksin tunnistaa myös zsh ja bash ja käyttää vain nimettyjä putkia järjestelmissä, jotka ' t: llä on /dev/fd/n.
  • @StephaneChazelas Kyllä, useimmat kuoret tukevat sitä, mutta se ' ei ole POSIX, joten siihen ' ei voida luottaa olevan kaikkialla.
  • Kyllä, huomautin vain, että prosessin korvaaminen ei ollut bash keksintö, koska vastauksesi sanamuoto voi antaa uskoa.
  • @TheLibbster Riippuu siitä, miten määrität tehokkaasti. Tähän menetelmään liittyy kahden uuden prosessin kuteminen, missä sed ja awk ovat vain yksi. Mutta tee ja wc ovat molemmat erittäin pieniä (paljon pienempiä kuin sed ja awk).
  • @TheLibbster kyllä, joidenkin juuri tekemieni yksinkertaisten testien mukaan se ' on oikeastaan noin kaksi kertaa nopeampi sekä sed – että awk -menetelminä. (I dd d 100mb tiedostoa /dev/urandom tiedostoon ja juoksin sitten kyseisen tiedoston läpi useita kertoja)

Vastaus

Yksi vaihtoehto on käyttää awk-tiedostoa, joka voi laskea ja tulostaa vakiona.

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

Kohdassa awk NR on nykyinen rivinumero. Voit tehdä saman perlillä:

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

Tai sed:

program | sed -n "p;$=" 

Kommentit

  • Onko mahdollista näyttää ulostulo sellaisenaan (rivi riviltä) ja palauttaa sitten luku lopussa ?

Vastaa

suosikkivaihtoehtoni:

program | grep "" -c 

kommentit

  • OP on saattanut kysyä jotain muuta, mutta tulin tänne etsimään vain saada lähtöjen rivien lukumäärä ja en ' ei välitä todellisen tuotoksen näyttämisestä, ja tämä tekee työn. Kiitos!

Vastaa

Voit kloonata stdoutin stderr-tiedostoon.

program | tee /dev/stderr | wc -l 

Tällä tavoin program” stdout lähetetään tee -ohjelmaan kirjoitettavaksi stderr-tiedostoon, joka on tulostettu konsolille. tee myös kirjoittaa siihen syötetyt tiedot vakiotilaansa, joka lähetetään osoitteeseen wc.

vastaus

Tämä saattaa olla myöhäistä. Mutta haluaisin vain vastata jatkokysymykseesi siitä, kuinka laskettu luku saadaan muuttujaan. >

Tämän haluat YOUR_VAR=$(PROGRAM | tee /dev/stderr | wc -l).

Hyödynnämme tee -tekniikan luomisen tässä kaksi virtaa ja ohjaa yksi osoitteeseen /dev/stderr, joka näytetään ruudulla, ja toinen osoitteeseen wc -l, joka raportoi rivien määrän.

Vastaa

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) 

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *