如何在不捕获注释的情况下对源代码进行 grep

如何在不捕获注释的情况下对源代码进行 grep

我搜索了一种在源代码上进行 grep 的方法,而不会因为注释而有时出现误报。例如,如果我在此 .c 源代码上搜索 foo :

/* 
 * foo has changed [...] and is now a 2-parameters function
 */
// foo(24)
foo(42, 28);

天真的人grep会发现 3 次出现,而我只想要 1 次。我见过这边走在 StackOverflow 上执行此操作,但它不能满足我的需求:PHP 在该平台上不可用。我也发现了这边走对于一行评论,但它只解决了我的问题的一部分。

我需要使用经典的脚本工具(awk、sed、bash、grep 等),并且我需要它快速地即使有数千个文件。

您现在知道是否以及如何可以对源代码进行 grep,并且只能对源代码进行 grep 吗?

答案1

grep 适用于纯文本,并且不了解 C 程序的底层语法。因此,为了不搜索内部评论,您有多种选择:

  1. 在搜索之前剥离 C 注释,您可以使用以下命令执行此操作。gcc -fpreprocessed -dD -E yourfile.c详细信息请参见https://stackoverflow.com/questions/2394017/remove-comments-from-cc-code

  2. 编写/使用一些像您已经发现的半工作脚本(例如,它们通过跳过以//或开头的行来工作/*),以便处理所有可能的 C/C++ 注释的详细信息(再次,请参阅前面的链接以获取一些可怕的测试用例) 。那么您仍然可能会出现误报,但您不必进行任何预处理。

  3. 使用更高级的工具在代码中进行“语义搜索”。我找到了“coccigrep”:http://home.regit.org/software/coccigrep/这种工具允许搜索某些特定的语言语句(即具有给定名称的结构的更新),当然它们会删除注释。

答案2

您可以尝试一种简单的方法来匹配非注释,如下所示:

 $ egrep -v "^(//|/\*| \*)" sourcecode

这只会与前缀注释反向匹配 - 即以//, /*,*或开头的行*/- 因此它不会遗漏用/*和 对注释掉的块*/

答案3

对于我们这些后来才回答这个问题的人来说,这是一个具体的变体:

ls -1 src/*.c | xargs -i sh -c "echo;gcc -fpreprocessed -dD -E {} 2>&1 | grep -wi -e one -e two -e three -n | sed 's:^:{}\::'" | cat -s

C 源文件列表

ls -1 src/*.c

通过管道传输到 xargs,它在子 shell 中执行预处理器

gcc -fpreprocessed -dD -E {} 2>&1

随后通过管道输送到所需的 grep 命令中

grep -wi -e one -e two -e three -n

然后通过管道传输到 sed 中,以当前文件名作为每行的前缀

sed 's:^:{}\::'

最后,使用 cat 将所有重复的空白行折叠为单行:

cat -s

这适用于 RHEL6 系统,但我认为它对于其他 *nix 系统来说已经足够通用了。

相关内容