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, на якому навіть, схоже, немає тегу regex. Це sortне є суворо необхідним, оскільки вихід грепа відсортований за номером рядка, але, мабуть, це було гарною практикою раніше uniq.
Кріс Х

2
Можливо, це не позначено, regexтому що регулярний вираз - це легка частина.
Том Зіч

Це насправді потрібно sort -n? Це все одно не виходить у порядку замовлення номера?
Том Зич

Ви маєте рацію, sort -nне потрібно. Спасибі.
Moebius

@TomZych, виявилось, ти маєш рацію, але якби я знав, що, можливо, не запитував. Психічний стрибок від grep до тегу: хоч регулярний вислів був трохи занадто великим.
Кріс Х

3

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

while read i; do echo $i |grep -o "matchingString"| wc -l;  done < input.txt

3
Найкраще рішення, на мій погляд. Може бути ще більш спрощена за рахунок зменшення однієї труби: grep -o "matchingString" <<< $i | wc -l.
Бенджамін В.

1
Це буде на порядок повільніше, ніж інші варіанти, проте
Рахул

1

Чи використовується grepвимога? Ось альтернатива:

sed 's / [^ {}] // g' ваш_файл | awk '{друк NR, довжина}'

Ці sedсмужки з усіх , крім символів {і } (тобто, залишивши тільки {і }символи), а потім awkпідраховувати символи в кожному рядку (які тільки {і }символи). Щоб придушити лінії без збігів,

sed 's / [^ {}] // g' ваш_файл | awk '/./ {друк NR, довжина}'

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

{ "nullfunc() {}" }

вважатиметься, що містить чотири символи дужок.


grepнасправді це не було вимогою, саме там я почав шукати рішення, бо це дало мені щось близьке. У мене ніколи не було потреби в буд, тому, якби я не використав відповідь вище, я використав би це як шанс експериментувати - я все ще можу. Те, що я не зміг зрозуміти (але це не впливає ні на одну відповідь), - це те, що я хотів запустити сценарій один раз у дужці, щоб допомогти мені виявити невідповідність (у джерелі LaTeX, тут для таблиці), де зустрічається більшість пар єдиний рядок.
Кріс Х

Я не зовсім впевнений, що ви маєте на увазі під „запуском сценарію один раз у дужці”, але якщо ви хочете виявити невідповідність дужок, ви можете спробувати щось на зразок sed 's/{[^{}]*}//g' your_file | grep –n '[{}]', де sedсмужки викреслюють (збігаються) пари. Якщо у вас вкладені пари, використовуйте sed 's/{[^{}]*}//g;s/{[^{}]*}//g;s/{[^{}]*}//g;…' …, повторюючи s/{[^{}]*}//gстільки разів, скільки глибоке гніздування.
Скотт

Я мав на увазі виконати `sed 's / [^}] // g' ваш_файл | awk '{print NR, length}' та 's / [^ {] // g' your_file | awk '{друк NR, довжина}'. У мене справді є гніздування, і відпрацювання найглибшого рівня здавалося клопотом. Перетворення багатьох рядків у жменю (є кілька випадків, коли дужки співпадають лише через кілька рядків з поважних причин) спрацював добре (я використовую jedit, який підкреслює відповідні дужки - для будь-якого типу дужок, який він розуміє - так що я дійсно зробив просто потрібно його звузити).
Кріс Х
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.