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
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)onkshsyntaksin tunnistaa myöszshjabashja 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
bashkeksintö, 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ä
sedjaawkovat vain yksi. Muttateejawcovat molemmat erittäin pieniä (paljon pienempiä kuinsedjaawk). - @TheLibbster kyllä, joidenkin juuri tekemieni yksinkertaisten testien mukaan se ' on oikeastaan noin kaksi kertaa nopeampi sekä
sed– ettäawk-menetelminä. (Iddd 100mb tiedostoa/dev/urandomtiedostoon 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)
STDOUT_WRITE_COUNT) tai kirjaa se tiedostoon / sovellusliittymään ohjelman lopussa. WDYT?