Spočítat počet řádků výstupu z předchozího programu

Snažím se spočítat počet řádků výstupu, které určitý program produkuje. Problém je v tom, že program spuštění trvá dlouho a chci uživateli zobrazit výstup. Existuje způsob, jak spočítat počet řádků, které vydal poslední příkaz?

Nemohu udělat program | wc -l, ale to by uživateli neukazovalo výstup. Pokud vím, musím udělat program; program | wc -l – ale spuštění programu trvá minimálně minutu, takže to nechci dělat víc než jednou v dolní části se zobrazí počet řádků.

EDIT:

  • Existuje způsob, jak zobrazit výstup tak, jak se to stane (řádek po řádku), a poté na konci vrátit počet?

Komentáře

  • Jak na to: nechat program sledovat svůj vlastní výstup a pouze načíst tuto hodnotu z proměnné (např. STDOUT_WRITE_COUNT) nebo jej přihlaste do souboru / API na konci programu. WDYT?

Odpovědět

Pomocí tee můžete rozdělit výstupní proud a odeslat jednu kopii na wc a druhá kopie do STDOUT jako normální.

program | tee >(wc -l) 

>(cmd) je bash syntax, což znamená ru n cmd a bit >(cmd) nahraďte cestou k (pojmenovanému kanálu připojenému k) programu STDIN.

Komentáře

  • >(cmd) je ksh syntaxe také rozpoznána zsh a bash a používá pouze pojmenované kanály v systémech, které <

nemá /dev/fd/n.

  • @StephaneChazelas Ano, většina skořápek to podporuje, ale ' není v POSIX, takže se na něj ' nelze spolehnout, že bude všude.
  • Ano, jen jsem poukazoval na to, že substituce procesu nebyla bash vynález, protože formulace ve vaší odpovědi by mohla člověku uvěřit.
  • @TheLibbster Záleží na tom, jak definujete efektivní. Tato metoda zahrnuje vytvoření 2 dalších procesů, kde jako sed a awk jsou jen jeden. Ale tee a wc jsou oba extrémně malé (mnohem menší než sed a awk).
  • @TheLibbster ano, podle několika jednoduchých testů, které jsem právě udělal, je to ' ve skutečnosti asi dvakrát rychlejší jako metody sed i awk. (dd d 100 mb /dev/urandom do souboru a poté tento soubor několikrát spustit každou metodou)
  • Odpověď

    Jednou z možností je použití awk, které dokáže počítat a tisknout na standardní výstup.

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

    V awk je NR číslo aktuální linky. Totéž můžete dosáhnout pomocí perl:

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

    Nebo sed:

    program | sed -n "p;$=" 

    Komentáře

    • Existuje způsob, jak zobrazit výstup tak, jak k němu dojde (řádek po řádku) a poté na konci vrátit počet ?

    Odpověď

    moje oblíbená možnost:

    program | grep "" -c 

    Komentáře

    • OP se možná zeptal na něco jiného, ale přišel jsem sem a hledal jen počet výstupů z počtu řádků a ne ' se nestará o zobrazení skutečného výstupu, a toto dělá svou práci. Děkujeme!

    Odpověď

    Stdout můžete klonovat na stderr.

    program | tee /dev/stderr | wc -l 

    Tímto způsobem se program“ stdout přesměruje na tee, který se zapíše do stderr, což je vytištěno na konzole. tee také zapíše data, která jsou k němu připojena, do svého standardního výstupu, který je odeslán do wc.

    Odpověď

    Může to být pozdě. Chtěl bych se ale jen zabývat vaší následnou otázkou, jak zachytit spočítané číslo v proměnné.

    To je to, co chcete YOUR_VAR=$(PROGRAM | tee /dev/stderr | wc -l).

    Využíváme výhod tee generování dvou proudů zde a nasměrujte jeden na /dev/stderr, který se zobrazí na vaší obrazovce, a druhý na wc -l, který ohlásí počet řádků.

    Odpověď

    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) 

    Napsat komentář

    Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *