Grep на macOS: найдите уникальные вхождения группы захвата в регулярном выражении

386
Dan Burzo

Я нахожусь на macOS и хотел бы использовать grep(или подобный инструмент), чтобы найти уникальные вхождения определенного шаблона в базе кода. Например, для поиска всех console.somemethod()вызовов в JavaScript я разработал:

grep -oiER "console\.([a-z]+)\(" . | sort -u 

Но это дает мне результаты в виде:

./tools/svg-inject/node_modules/with/node_modules/acorn/src/bin/acorn.js:console.log( ./tools/svg-inject/node_modules/wordwrap/README.markdown:console.log( ./tools/svg-inject/node_modules/wordwrap/example/center.js:console.log( ./tools/svg-inject/node_modules/wordwrap/example/meat.js:console.log( ./tools/svg-inject/node_modules/yargs/README.md:console.dir( ./tools/svg-inject/node_modules/yargs/README.md:console.log( ./tools/svg-inject/node_modules/yargs/index.js:console.log( ./tools/svg-inject/node_modules/yargs/lib/usage.js:console.error( ./tools/svg-inject/node_modules/yargs/lib/usage.js:console.log( ./webpack.config.js:console.info( Console.sendTo( console.error( console.log( console.markTimeline( console.reactStackEnd( console.timeEnd( console.trace( console.warn( 

Я хотел бы ограничить его уникальные матчи ([a-z]+)группы только :

info sendTo error log markTimeline reactStackEnd timeEnd trace warn 

Извиняюсь, если я перефразирую старый вопрос!

2
Каков ваш ожидаемый результат? Toto 6 лет назад 0
Упс, добавил ожидаемый результат к вопросу. Dan Burzo 6 лет назад 0
Обычно я бы использовал `sed` для такого рода вещей, но он работает только с определенным списком файлов (без опции` -R`). Вы можете передать существующий вывод `grep` через` sed`, но это не дает никакого преимущества по сравнению с передачей через `perl` или второй` grep`, как в ответе @ Toto. Если вы знаете глубину дерева каталогов, вы можете использовать `sed -n 's /^.* console \. \ ([Az] + \) (. * $ / \ 1 / p' * * / * * / * / * * / * / * / * | sort -u` (для трех уровней подкаталога). Стоит познакомиться с `sed` и [this] (http://www.grymoire.com/unix/sed .html) хорошее введение. AFH 6 лет назад 1

1 ответ на вопрос

2
Toto

Используйте -Pпараметр для регулярного выражения perl с \Kдирективой в регулярном выражении, которая исключит совпадение предыдущей части строки из результата:

grep -ioP "console\.\K[a-z]+" file.txt log log log log dir log log error log info sendTo error log markTimeline reactStackEnd timeEnd trace warn 

Я поместил ваш пример строки в file.txt для тестирования.

Чтобы ограничить уникальное вхождение:

grep -ioP "console\.\K[a-z]+" file.txt | sort -u dir error info log markTimeline reactStackEnd sendTo timeEnd trace warn 

Другой -P вариант решения был удалить версию MacOS10.8

Если у вас установлен Perl:

perl -nle 'print $1 if /console\.([a-z]+)/' file.txt | sort -u dir error info log mark react time trace warn 

Для работы со всеми файлами в каталоге:

perl -nle 'print $1 if /console\.([a-z]+)/' * | sort -u 
oof, я забыл упомянуть, что я нахожусь на macOS, и команда, кажется, не работает (возможно, отсутствует флаг `-P`). Dan Burzo 6 лет назад 0
@Dan: Посмотрите мое редактирование, оно должно работать, если у вас установлен Perl Toto 6 лет назад 1
Ааа, почти нет! Есть ли шанс, что он будет работать рекурсивно в текущей папке, чтобы соответствовать всем файлам? Dan Burzo 6 лет назад 0
Это последняя, ​​великолепная форма: `найди. -exec perl -nle 'вывести $ 1, если /console\.([az]+)\(/i' {} + | sort -u` Dan Burzo 6 лет назад 0
@Dan: или, конечно, замените `file.txt` на` * ` Toto 6 лет назад 0
(Я пробовал с `./**/*. Js`, но я получил ошибку` список аргументов слишком длинный`) Dan Burzo 6 лет назад 0
@ Дан: Пожалуйста, рад, что это помогает. Toto 6 лет назад 0