Команда Bash для подсчета строк с совпадающими подстроками в двух разных позициях

Команда Bash для подсчета строк с совпадающими подстроками в двух разных позициях

Я пытаюсь получить некоторую тривиальную статистику по некоторым отладочным выводам.

Каждая отладочная строка имеет вид(class name)(delimiter 1)(object ID)(delimiter 2)(method name)(delimiter 3)(log message)

Я хочу подсчитать, сколько строк поступает из разных методов.

По сути, если каждую строку можно сократить до (class name)(delimiter)(method name), я хочу узнать, сколько раз каждое из этих сокращений встречается в файле журнала.

Какую команду можно выполнить в Bash для подсчета?

(Я делаю это на macOS с помощью macports, заменяя большинство стандартных инструментов в стиле BSD на инструменты GNU.)

Я могу извлечь имя класса с помощью grep -o -E "^.*(delimiter 1), или извлечь имя метода с помощью grep -o -E "(delimiter 2).*(delimiter 3)", или выделить оба с помощью grep --color=always -E "^.*(delimiter 1)|(delimiter 2).*(delimiter 3)". Я застрял, ища способ вывести grepтолько два совпадения, которые затем можно было бы запустить | uniq -cдля подсчета.

Есть ли способ вывести grepоба совпадения для каждой строки, а не только одно совпадение или всю строку целиком?

решение1

По сути, это можно сделать с помощью

sed -r -n 's/(^.*)(delimiter 1)(.*)(delimiter 2)(.*)(delimiter 3)(.+$)/\1(delimiter)\5/p' <( command that generates debug logs ) | sort | uniq -c | sort -rn

(адаптирован изздесь)

  • .*может соответствовать слишком многому; sedявляется жадным и хочет соответствовать как можно большему количеству как можно раньше, поэтому это могут быть, например, отрицания разделителей (что может быть сложно, если у вас неудобные разделители)
  • Переход от ^к $важен, если ваше выражение не совпадает со всей строкой, sedнесоответствующая часть будет включена в вывод.
  • Скобки необходимы только вокруг имени класса и имени метода; удаление остальных означает изменение цифр в конце, поскольку цифры ссылаются на заключенные в скобки подвыражения по порядку. (Включение их всех позволяет показать больше того, что происходит в выводе sed, например, путем изменения окончания на /\1(delimiter)\5 -- \1\2\3\4\5\6\7/p)
  • sortдолжен быть запущен раньше, uniq -cтак как uniq -cподсчитываются только серии последовательных идентичных строк, непоследовательные идентичные строки получают отдельные подсчеты
  • uniq -cне может быть заменен, sort -uпотому что sort -uтолько удаляет дубликаты, он их не учитывает
  • Финал sortне обязателен для ответа на заданный вопрос.
  • Да, если вы используете регулярные выражения для решения проблемы, то у вас возникает две проблемы.

Связанный контент