Come misurare la dimensione dei dati convogliati?


16

Vorrei fare qualcosa del genere:

> grep pattern file.txt | size -h
16.4 MB

o qualcosa di equivalente a:

> grep pattern file.txt > grepped.txt
> ls -h grepped.txt
16.4 MB
> rm grepped.txt

(sarebbe un po 'scomodo, però)

È possibile?

Risposte:


32

Puoi usare wcper questo:

grep pattern file.txt | wc -c

conterà il numero di byte nell'output. È possibile post-elaborarlo per convertire valori di grandi dimensioni in un formato "leggibile dall'uomo" .

È inoltre possibile utilizzare pvper ottenere queste informazioni all'interno di una pipe:

grep pattern file.txt | pv -b > output.txt

(visualizza il numero di byte elaborati, in formato leggibile dall'uomo).


1
Preferisco wc -cperché du -hrestituisce `4.0 K` se è inferiore a 4,0k mentre legge in blocchi
Stan Strum,

Se la stampa dell'output in MB è sufficiente, il comando potrebbe essere | wc -c | sed 's/$/\/1024\/1024/' | bc. Ciò si aggiunge /1024/1024all'output ed esegue una calcolatrice sulla stringa risultante.
phil294

9

È possibile utilizzare lo strumento pipeviewer pvcon l'indicatore di conteggio byte totale -b:

$ dd if=/dev/zero bs=3 count=4211 2>/dev/null | pv -b >/dev/null
12.3KiB

$ grep pattern file.txt | pv -b >/dev/null

3

L' utility Pipe Viewer è stata progettata per questo scopo. Se non è abbastanza flessibile per i tuoi scopi, puoi implementare il tuo codice di misurazione del trasferimento dati FIFO con le chiamate di funzione della libreria di manipolazione della pipeline ( libpipeline ) come pipeline_pump()e pipeline_peek_size().

$ whatis pv
pv (1)               - monitor the progress of data through a pipe
$ pv -Wi 0.002 -cf /etc/hosts | wc -l
 367 B 0:00:00 [2.71MiB/s] 
[============================================================================>] 
100%
10
$

1

Si potrebbe preparare rapidamente la propria soluzione in Python:

#!/usr/bin/env python
import sys

count = 0
while True:
    byte = sys.stdin.read(1)
    if not byte:
        break
    count =  count + 1

print(count)

Funziona così:

$ echo "Hi" | ./count_stdin_bytes.py
3
$ echo "Hello" | ./count_stdin_bytes.py
6
$ dd if=/dev/zero bs=1 count=1024 2>/dev/null |  ./count_stdin_bytes.py 
1024

Dal momento che nel vostro caso particolare hai a che fare con dati di testo (a giudicare dal fatto che il tubo da grep), si potrebbe anche fare uso di bashs' read. Qualcosa come questo:

$ echo "Hello" | { while read -n 1 char; do ((count++)) ;done ; echo $count; }
6

Perché è meglio di wc -c? while read ...probabilmente sarà significativamente più lento. Inoltre, OP ha chiesto un output leggibile dall'uomo come in ( ls -h)
phil294
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.