Grep: подсчет количества совпадений в строке

26

Я пытаюсь получить количество совпадений (в данном случае вхождений {или }) в каждой строке файла .tex.

Я знаю, что -oфлаг возвращает только совпадение, но он возвращает каждое совпадение на новой строке, даже в сочетании с -nфлагом. Я не знаю ничего, что я мог бы передать это через подсчет повторов. -cФлаг только возвращает общее количество совпадений весь файл - возможно , я мог бы труба одна линия в то время , чтобы Grep?

Крис Х
источник

Ответы:

27
grep -o -n '[{}]' <filename> | cut -d : -f 1 | uniq -c

Результат будет примерно таким:

3 1
1 2

Значение 3 вхождения в первой строке и 1 во второй.

Взято с /programming//a/15366097/3378354 .

Мебиус
источник
Спасибо - Google обнаружил множество совпадений с регулярным выражением в SU, но не в SO, который, похоже, даже не имеет тега регулярного выражения. Это sortне является строго необходимым, поскольку вывод grep сортируется по номеру строки, но я думаю, что это хорошая практика раньше uniq.
Крис Х
2
Вероятно, не помечены, regexпотому что регулярное выражение является легкой частью.
Том Зыч
Это действительно необходимо sort -n? Разве это не выходит в порядке номеров строк в любом случае?
Том Зыч
Вы правы, sort -nне обязательно. Спасибо.
Мобиус
@ TomZych, оказалось, ты был прав, но если бы я знал, что, возможно, не спросил. Мысленный переход от grep к тегу: регулярное выражение, возможно, было слишком много, хотя.
Крис Х
3

Прочитав различные решения, я думаю, что это самый простой подход к проблеме:

while read i; do echo $i |grep -o "matchingString"| wc -l;  done < input.txt
alfredocambera
источник
3
Лучшее решение, на мой взгляд. Может быть еще более упрощена за счет уменьшения одной трубы: grep -o "matchingString" <<< $i | wc -l.
Бенджамин В.
1
Это будет на порядки медленнее, чем другие варианты, хотя
Рахул
1

Используете grepли вы требование? Вот альтернатива:

sed 's / [^ {}] // g' your_file | awk '{print NR, length}'

Эти sedполоски из всех , кроме символов {и } (то есть, оставив только {и }символы), а затем awkподсчитывать символы в каждой строке (которые только {и }символы). Чтобы подавить строки без совпадений,

sed 's / [^ {}] // g' your_file | awk '/./ {print NR, length}'

Обратите внимание, что мое решение предполагает (требует), что строки, которые вы ищете, являются одиночными символами. Ответ Мебиуса легче адаптировать к многосимвольным строкам. Кроме того, ни один из наших ответов не исключает цитируемые или экранированные вхождения символов / строк, представляющих интерес; например,

{ "nullfunc() {}" }

будет считаться содержать четыре символа скобки.

Скотт
источник
grepна самом деле это не было требованием, я просто начал искать решение, потому что оно дало мне что-то близкое. У меня никогда не было необходимости в awk, поэтому, если бы я не использовал ответ выше, я бы использовал это как шанс для экспериментов - я все еще могу. Что я не смог уточнить (но это не влияет ни на один из ответов), так это то, что я хотел запустить скрипт один раз для каждой скобки, чтобы помочь мне отследить несоответствие (в источнике LaTeX, здесь для таблицы), где большинство пар встречаются в одна строка.
Крис Х
Я не совсем уверен, что вы подразумеваете под «запускать сценарий один раз в скобках», но если вы хотите отследить несоответствие фигурных скобок, вы можете попробовать что-то наподобие того sed 's/{[^{}]*}//g' your_file | grep –n '[{}]', где sedвырезаются (совпадают) пары. Если у вас есть вложенные пары, используйте sed 's/{[^{}]*}//g;s/{[^{}]*}//g;s/{[^{}]*}//g;…' …, повторяя s/{[^{}]*}//gстолько раз, сколько ваша самая глубокая вложенность.
Скотт
Я имел в виду выполнить `sed 's / [^}] // g' your_file | awk '{print NR, length}' и 's / [^ {] // g' your_file | awk '{print NR, length}'. У меня действительно есть вложение, и разработка самого глубокого уровня казалась рутиной. Превращение многих строк в несколько (есть несколько случаев, когда фигурные скобки совпадают только по нескольким строкам по уважительным причинам) работало хорошо (я использую jedit, который выделяет совпадающую скобку - для любого типа скобок, который он понимает - так что я действительно сделал просто нужно сузить)
Крис Х