Чтобы посчитать количество совпадений в мега-строке быстро

У меня есть большие текстовые данные без пробелов и без других строк в одной строке. На самом деле, потоки составляют 0,2 Гбит / с, аналогичная ситуация здесь , но в этой задаче подсчет вхождений, которые сложнее вычислительны, чем просто подсчет пустых строк. Матч

585e0000fe5a1eda480000000d00030007000000cd010000 

Пример подмножества данных здесь называется 30.6.2015_data.txt и его полные двоичные данные, называемые 0002.raw . Матч встречается 1 раз в 30.6.2015_data.txt, но 10 раз в полных данных 0002.raw в одной строке. Я подготовил txt-данные по xxd -ps 0002.raw > /tmp/1 && fold -w2 /tmp/1 > /tmp/2 && gsed ':a;N;$!ba;s/\n//g' /tmp/2 > /tmp/3 . Чем быстрее реализация, тем лучше. Чтобы подготовить мега строку в столбце, вы можете использовать этот xxd -ps 0002.raw > /tmp/1 && fold -w2 /tmp/1 > /tmp/2 . Моя текущая ставка составляет 0,0012 с за матч, то есть 0,012 с за десять матчей в полном файле данных, что происходит медленно.

Греп делает это в строках, что невозможно в подсчете. В Vim %s/veryLongThing//gn недостаточно для задачи. Команда wc дает только символ, байт и строки, поэтому не корректирует инструмент, но, вероятно, комбинируя его с чем-то другим. Возможно, сочетание GNU Find и Sed, но все реализации кажутся слишком сложными.

Выводы ответа Mikeserv

 $ cat 1.7.2015.sh time \ ( export ggrep="$(printf '^ \376Z\36\332H \r \3 \a \315\1')" \ gtr='\1\3\a\r\36HZ^\315\332\376' LC_ALL=C gtr -cs "$gtr" ' [\n*]' | gcut -sd\ -f1-6 | ggrep -xFc "$ggrep" ) <0002.raw $ sh 1.7.2015.sh 1 real 0m0.009s user 0m0.006s sys 0m0.007s ----------- $ cat 1.7.2015.sh time \ ( set x58 x5e x20 x20 xfe x5a x1e xda \ x48 x20 x20 x20 x0d x20 x03 x20 \ x07 x20 x20 x20 xcd x01 x20 x20 export ggrep="$(shift;IFS=\\;printf "\\$*")" \ gtr='\0\1\3\a\r\36HXZ^\315\332\376' \ LC_ALL=C i=0 while [ "$((i+=1))" -lt 1000 ] do gcat 0002.raw; done | gtr -cd "$gtr" |gtr 'X\0' '\n ' | gcut -c-23 |ggrep -xFc "$ggrep" ) $ sh 1.7.2015.sh 9990 real 0m4.371s user 0m1.548s sys 0m2.167s 

где все инструменты являются GNU coreutils, и у них есть все опции, которые вы предоставляете в коде. Однако они могут отличаться GNU devtools. Mikeserv запускает свой код 990 раз, и есть 10 событий, поэтому итоговые 9990 событий правильные.

Как вы можете рассчитывать количество матчей в мегаэффекте эффективно?

  • Определить динамически выделенный порт для OpenSSH RemoteForward
  • как выполнять команды на удаленном сервере как разные пользователи
  • создание динамического случая
  • Массовое переименование и изменение размера с помощью Imagemagick
  • Скрипт с использованием sudo работает с терминала, но не с ярлыка на рабочем столе
  • Объединение нескольких файлов в один CSV
  • Использование sed для замены строки со многими специальными символами?
  • Есть ли способ сделать этот однострочный лайнер быстрее?
  • 2 Solutions collect form web for “Чтобы посчитать количество совпадений в мега-строке быстро”

    GNU-реализация grep (также найденная в большинстве современных BSD, хотя последние версии – полная (в основном совместимая) переписывающая), поддерживает опцию -o для вывода всех согласованных частей.

     LC_ALL=C grep -ao CDA | wc -l 

    затем будет подсчитывать все вхождения.

     LC_ALL=C grep -abo CDA 

    чтобы найти их со своим байтовым смещением.

    LC_ALL=C гарантирует, что grep не будет пытаться выполнить некоторый дорогостоящий синтаксический анализ UTF-8 (хотя здесь с фиксированным поиском строк ASCII grep должен иметь возможность оптимизировать синтаксический анализ UTF-8). -a – еще один GNUism, чтобы сказать grep рассмотреть двоичные файлы.

    Поэтому я взял вашу шестую строку и распечатал ее в байтах, но я заменил NULs на <spaces> (в основном потому, что не могу понять, как получить NUL в шаблоне grep ) :

     time \ ( set x58 x5e x20 x20 xfe x5a x1e xda \ x48 x20 x20 x20 x0d x20 x03 x20 \ x07 x20 x20 x20 xcd x01 x20 x20 export grep="$(shift;IFS=\\;printf "\\$*")" \ tr='\0\1\3\a\r\36HXZ^\315\332\376' \ LC_ALL=C i=0 while [ "$((i+=1))" -lt 1000 ] do cat 0002.raw; done | tr -cd "$tr" |tr 'X\0' '\n ' | cut -c-23 |grep -xFc "$grep" ) 

    Переменная tr состоит из восьмеричных escape-последовательностей / символов ASCII для байтовых значений вашей шестнадцатеричной строки, потому что я хотел tr -d elete ее дополнение. Затем я убедился, что самая длинная строка grep может попытаться сопоставить с -c-23 байта с cut и что строка всегда будет возглавлять строку путем tr анслирования X-символов в \n ewlines, а также для замены NUL для <пробелов >.

    Я кочую сырую двоичную систему на конвейере 999 раз здесь. Поскольку в файле 10 совпадений, результаты:

     9990 1.06s user 0.94s system 65% cpu 3.054 total 

    Теперь я также тестировал …

     time \ ( set x58 x5e x20 x20 xfe x5a x1e xda \ x48 x20 x20 x20 x0d x20 x03 x20 \ x07 x20 x20 x20 xcd x01 x20 x20 export LC_ALL=C i=0 grep="$(IFS=\\;printf "\\$*")" while [ "$((i+=1))" -lt 1000 ] do cat 0002.raw; done | tr '\0 ' ' \0' | grep -aFo "$grep"| wc -l ) 

    Я использую wc -l там, но в моих тестах, похоже, не было никакого разного времени, чтобы использовать -caFo и вообще отказаться от wc . Во всяком случае, подсчеты были одинаковыми. Результаты для этого:

     9990 1.56s user 1.46s system 82% cpu 3.648 total 

    Теперь эти два набора команд не эквивалентны. Хотя, похоже, он немного ускоряется, сначала вытесняя ненужные байты w / tr , но это означает, что вы можете получить счет, вы не можете получить смещения, как вы могли бы, добавив -b переключатель в grep во второй пример…

     time \ ( set x58 x5e x20 x20 xfe x5a x1e xda \ x48 x20 x20 x20 x0d x20 x03 x20 \ x07 x20 x20 x20 xcd x01 x20 x20 export LC_ALL=C i=0 grep="$(IFS=\\;printf "\\$*")" while [ "$((i+=1))" -lt 1000 ] do cat 0002.raw; done | tr '\0 ' ' \0' | grep -baFo "$grep" | sed -nl ) 

     ... 241133568:X^ \376Z\036\332H \r \003 \a \315\001 $ 241157720:X^ \376Z\036\332H \r \003 \a \315\001 $ 241181872:X^ \376Z\036\332H \r \003 \a \315\001 $ 241206024:X^ \376Z\036\332H \r \003 \a \315\001 $ 241230176:X^ \376Z\036\332H \r \003 \a \315\001 $ 241254328:X^ \376Z\036\332H \r \003 \a \315\001 $ 1.59s user 1.41s system 85% cpu 3.496 total 

    И так, что вы выбираете, я думаю, будет зависеть от того, что вы хотите. Для просто счет, возможно, tr -cd будет лучше – он надежно завершает половину секунды быстрее, чем другой каждый раз, но это не так много, и, возможно, если ваш grep будет поддерживать его, grep -baFo может быть что вам нужно.

    Interesting Posts

    Устанавливает ли несвободное программное обеспечение из несвободных репозиториев Debian пиратство?

    запуск LXDE автоматически (без Диспетчера отображения)

    Как исключить файлы / каталоги из find с помощью аргумента программы в bash?

    Ищете что-то вроде gnome2 погодных часов для KDE

    Как получить значение последнего дня в текущем месяце в awk

    Не удается подключиться к ssh

    Файл pre-seed Debian PXE

    Проверьте входящий поток на пустые пространства и переместите его

    Как изменить IP-адрес моего компьютера?

    Где я могу найти температуру и частоту процессора без какой-либо конкретной команды?

    Как установить пакет wget на сервер aix 7.1 без локального хранилища?

    Как разрешить аутентификацию с помощью `sudo` с помощью альтернативного пароля?

    Нуво-курсор "разрывает"

    использование для эха без аргументов в сценариях оболочки

    Если моя программа обнаруживает, что потеря мощности произойдет через несколько секунд, что она может сделать, чтобы избежать повреждения данных?

    Linux и Unix - лучшая ОС в мире.