4

I am on macOS and would like to get into using grep (or a similar tool) to find unique occurrences of a certain pattern in a codebase. For example, for finding all console.somemethod() calls in JavaScript I have devised:

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

But this gets me results in the form:

./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(

I would like to restrict it to unique matches of the ([a-z]+) group only:

info
sendTo
error
log
markTimeline
reactStackEnd
timeEnd
trace
warn

Apologies if I'm rehashing an old question!

3
  • What is your expected result?
    – Toto
    Sep 6, 2018 at 9:58
  • Oops, added the expected result to the question.
    – Dan
    Sep 6, 2018 at 10:00
  • 1
    Normally, I'd use sed for this sort of thing, but it works only with a specific file list (no -R option). You can pipe the existing grep output through sed, but this gives no advantage over piping through perl or a second grep, as in @Toto's answer. If you know the depth of the directory tree, you can use sed -n 's/^.*console\.\([a-z]+\)(.*$/\1/p' * */* */*/* */*/*/*|sort -u (for three levels of subdirectory). It's worth getting to know sed, and this is a good introduction.
    – AFH
    Sep 6, 2018 at 10:38

1 Answer 1

4

Use the -P option for perl regex with \K directive in the regex that will exclude the preceding string part matching from the result:

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

I have put your example lines in file.txt to test.

To restrict to uniq occurrence:

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

Another solution -P option has been remove macOS version 10.8

If you have perl installed:

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

In order to work with all files in the directory:

perl -nle 'print $1 if /console\.([a-z]+)/' * | sort -u
7
  • 4
    oof, I forgot to mention I'm on macOS and the command doesn't seem to work (it may be missing the -P flag).
    – Dan
    Sep 6, 2018 at 10:20
  • 1
    @Dan: See my edit edit, it should work if you have perl installed
    – Toto
    Sep 6, 2018 at 10:31
  • Aah, almost there! Is there any chance it will work recursively in the current folder to match all files?
    – Dan
    Sep 6, 2018 at 10:36
  • This is the final, glorious form: find . -exec perl -nle 'print $1 if /console\.([a-z]+)\(/i' {} + | sort -u
    – Dan
    Sep 6, 2018 at 10:47
  • @Dan: Or course, change file.txt to *
    – Toto
    Sep 6, 2018 at 10:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .