2

I'm trying to search a substantial C++ codebase for a single line that is outputing text to the terminal that I'd like to suppress. I have grepped for std::cout and have had around 40 different files returned. The problems I face are:

  • I did not add this myself so I have no idea where it is.
  • It is a pointer only outputing memory location so I have no context in which to search for it.
  • The codebase is enourmous and contains a great many other instances of sdt::cout that have once been used for debugging purposes and have since been commented out.

My question pertains to the last one. I am using

grep -rle 'std::cout' .

to search, which will return positive for instances of std::cout, //std::cout, // std::cout and any other occurence of std::cout sitting on a line that is actually commented out.

How can I modify my grep to omit any line containing // so I can eliminate the commented lines?

3
  • 1
    This might solve your problem, without -l: grep -re 'std::cout' | grep -v '//'.
    – user4518
    Sep 30, 2011 at 14:37
  • From your description, it looks like you wouldn't want to match this line: std::cout << p; // just debug data
    – user4518
    Sep 30, 2011 at 14:38
  • 1
    "The codebase is enourmous and contains a great many other instances of sdt::cout that have once been used for debugging purposes and have since been commented out." This is why you create a separate function for logging debugs and use a define to enable/disable it. Sep 30, 2011 at 15:16

4 Answers 4

3

You could look for std::cout only when it isn't preceded by //. Regexp syntax does not include negation; every regexp can be negated by writing out its complement, but the complement can grow huge. Here, it's not too big:

grep -rl -E '^/?([^/]/?)*std::cout' .

You can also list all occurrences of std::cout and filter away the occurrences of //.*std::cout, but note that this will hide things like std::cout << foo; // std::cout << bar;.

grep -r 'std::cout' . | grep -vE '^[^:]*:.*//.*std::cout' | sed -e 's/:.*//'

Alternatively, you can run a tool that parses the C++ code, such as ctags.

1
egrep -r '^([^/]/?)*std::cout' .
0
grep -r 'std::cout' . | grep -v '^[ \t]*//'

will only omit the commented out lines, and not all the lines that have a comment on them.

1
  • 2
    -l suppresses normal output, so you'd just filter filenames containing comments.
    – user4518
    Sep 30, 2011 at 16:04
0

Supplementing Gilles' answer, for a single file you can just do the whole thing in Sed with much greater simplicity:

sed -n 'h;s|//.*||;/std::cout/{g;p;}' file.c

In other words, just save (hold) the line, strip any trailing comment, then if the line matches the pattern you want, get the saved copy of the line and print it.

For recursive grep, though, use Gille's solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy