Как измерить размер передаваемых данных?

16

Я хотел бы сделать что-то вроде этого:

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

или что-то эквивалентное:

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

(это было бы немного неудобно, хотя)

Это возможно?

Раффаэль
источник

Ответы:

32

Вы можете использовать wcдля этого:

grep pattern file.txt | wc -c

будет считать количество байтов в выводе. Вы можете постобработать это, чтобы преобразовать большие значения в «читаемый человеком» формат .

Вы также можете использовать pvэту информацию внутри канала:

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

(отображает количество обработанных байтов в удобочитаемом формате).

Стивен Китт
источник
1
Я предпочитаю, wc -cпотому что du -hвозвращает `4.0 K`, если он меньше, чем 4,0k, поскольку он читается в блоках
Stan Strum
Если распечатки вывода в МБ достаточно, команда может быть | wc -c | sed 's/$/\/1024\/1024/' | bc. Это добавляет /1024/1024к выводу и запускает калькулятор для полученной строки.
phil294
9

Вы можете использовать инструмент pipeviewer pvс флагом общего количества байтов -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

Pipe просмотр утилита была разработана для этой цели. Если он недостаточно гибок для ваших целей, вы можете реализовать свой собственный код измерения передачи данных FIFO с помощью вызовов функций библиотеки манипулирования конвейером ( libpipeline ), таких как pipeline_pump()и 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

Можно быстро приготовить собственное решение на 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)

Работает так:

$ 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

Поскольку в вашем конкретном случае вы имеете дело с текстовыми данными (судя по тому, что вы передаете grep), вы также можете использовать bashs read. Что-то вроде этого:

$ echo "Hello" | { while read -n 1 char; do ((count++)) ;done ; echo $count; }
6
Сергей Колодяжный
источник
Почему это лучше чем wc -c? while read ...вероятно будет значительно медленнее. Кроме того, OP запросил удобочитаемый вывод, как в ( ls -h)
phil294