Sto cercando di contare il numero di righe di output prodotte da un determinato programma. Il problema è che il programma richiede molto tempo per essere eseguito e desidero visualizzare loutput per lutente. Cè un modo per contare il numero di righe emesse dallultimo comando?
Potrei fare program | wc -l ma questo non mostrerebbe loutput allutente. Per quanto ne so, devo fare program; program | wc -l – ma il programma impiega almeno un minuto per essere eseguito, quindi non voglio doverlo fare più di una volta per mostrare un conteggio delle righe in fondo.
EDIT:
- Esiste un modo per mostrare loutput mentre accade (riga per riga) e poi restituire un conteggio alla fine?
Commenti
Risposta
Puoi utilizzare tee per dividere il flusso di output inviando una copia a wc e laltra copia in STDOUT come al solito.
program | tee >(wc -l)
>(cmd) è la sintassi bash che significa ru n cmd e sostituire il bit >(cmd) con il percorso di (una pipe denominata collegata a) STDIN di quel programma.
Commenti
-
>(cmd)èkshsintassi riconosciuta anche dazshebashe utilizza solo named pipe su sistemi che non ' t avere/dev/fd/n. - @StephaneChazelas Sì, la maggior parte delle shell lo supporta, ma ' non è in POSIX, quindi ' non ci si può fidare per essere ovunque.
- Sì, stavo solo facendo notare che la sostituzione del processo non era un
bashinvenzione come la formulazione nella tua risposta potrebbe far credere. - @TheLibbster Dipende da come definisci efficiente. Questo metodo implica la generazione di 2 processi aggiuntivi, dove
sedeawksono solo uno. Mateeewcsono entrambi estremamente piccoli (molto più piccoli disedeawk). - @TheLibbster sì, secondo alcuni semplici test che ho appena fatto, ' in realtà è circa il doppio più veloce come entrambi i metodi
sedeawk. (Hoddd 100 MB di/dev/urandomin un file e poi ho eseguito il file attraverso ciascun metodo più volte)
Risposta
Unopzione è usare awk, che può eseguire il conteggio e stampare su stdout.
program | awk "{ print } END { print NR }"
In awk, NR è il numero di riga corrente. Puoi ottenere lo stesso risultato con perl:
program | perl -pe "END {print "$.\n"}"
Oppure sed:
program | sed -n "p;$="
Commenti
- Cè un modo per mostrare loutput mentre accade (riga per riga) e poi restituire un conteggio alla fine ?
Rispondi
la mia opzione preferita:
program | grep "" -c
Commenti
- OP potrebbe aver chiesto qualcosaltro, ma sono venuto qui cercando solo di ottenere un conteggio del numero di righe in uscita e non ' t interessa mostrare loutput effettivo, e questo fa il lavoro. Grazie!
Risposta
Puoi clonare stdout su stderr.
program | tee /dev/stderr | wc -l
In questo modo, program” s stdout viene reindirizzato a tee per essere scritto in stderr, che è stampato sulla console. tee scrive anche i dati inviati tramite pipe al suo stdout, che viene reindirizzato a wc.
Risposta
Potrebbe essere tardi. Ma vorrei solo rispondere alla tua domanda di follow-up su come catturare il numero contato in una variabile.
Questo è ciò che desideri YOUR_VAR=$(PROGRAM | tee /dev/stderr | wc -l).
Approfittiamo del fatto che tee generi due stream qui e indirizzarne uno a /dev/stderr, che verrà visualizzato sullo schermo, e laltro a wc -l, che riporterà il numero di righe.
Risposta
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) o registralo in un file / API alla fine del programma. WDYT?