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)
onksh
syntaksin tunnistaa myöszsh
jabash
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
jaawk
ovat vain yksi. Muttatee
jawc
ovat molemmat erittäin pieniä (paljon pienempiä kuinsed
jaawk
). - @TheLibbster kyllä, joidenkin juuri tekemieni yksinkertaisten testien mukaan se ' on oikeastaan noin kaksi kertaa nopeampi sekä
sed
– ettäawk
-menetelminä. (Idd
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)
STDOUT_WRITE_COUNT
) tai kirjaa se tiedostoon / sovellusliittymään ohjelman lopussa. WDYT?