grep是如何工作的?

时间:2011-08-21 07:04:38

标签: c shell unix grep gnu

我想了解grep的工作原理。

当我说grep "hello" *.*时,grep是否得到2个参数 - (1)要搜索的字符串,即“hello”和(2)路径*.*?或者shell会将*.*转换为grep可以理解的内容吗?

我在哪里可以获得grep的源代码?我遇到了这个GNU grep链接。其中一个README文件说它与unix grep不同。怎么样?

我想查看FreeBSD版本的grep以及它的Linux版本(如果它们不同)。

4 个答案:

答案 0 :(得分:21)

grep的力量是自动机理论的神奇之处。 GREP是Global Regular Expression Print的缩写。它的工作原理是构建一个自动机(一个非常简单的“虚拟机”:不是图灵完成);然后它“对输入流执行”自动机。

自动机是节点或状态的图形或网络。国家之间的过渡由受到审查的输入字符决定。像+*这样的特殊自动机通过循环返回自身来工作。像[a-z]这样的字符类由扇形表示:一个起始节点,每个字符的分支到“辐条”;并且通常辐条对单个最终状态具有特殊的“epsilon过渡”,因此它可以与从正则表达式(搜索字符串)构建的下一个自动机相关联。 epsilon转换允许更改状态,而不会在被搜索的字符串中向前移动。

编辑:看来我没有仔细阅读这个问题。

当您键入命令行时,它首先由shell预处理。 shell执行别名替换和文件名通配。在替换别名(它们就像宏)之后,shell将命令行切换为参数列表(以空格分隔)。此参数列表作为整数计数(通常称为argc)传递给可执行命令程序的main()函数,并指向以nul结尾的以NULL结尾((void *)0)数组的指针({{ 1}})char数组。

个别命令会根据自己的意愿使用他们的参数。但是,如果给出'\0'参数,大多数Unix程序都会打印友好的帮助消息(因为它以减号开头,它被称为选项)。 GNU软件也将接受“长格式”选项-h

由于不同版本的Unix程序之间存在很多差异,因此发现程序所需的确切语法的最可靠方法是询问程序本身。如果这不能告诉您需要什么(或者说它太难以理解),您应该接下来检查本地联机帮助页(--help)。对于gnu软件,您通常可以从man grep获得更多信息。

答案 1 :(得分:12)

shell执行globbing(从*表单转换为文件名)。如果你有一个简单的C程序,你可以看到这个:

#include <stdio.h>

int main(int argc, char **argv) {
    for(int i=1; i<argc; i++) {
        printf("%s\n", argv[i]);
    }
    return 0;
}

然后像这样运行:

./print_args *

你会看到它打印出匹配的内容,而不是字面上的*。如果你这样调用它:

./print_args '*'

你会看到它有文字*

答案 2 :(得分:5)

shell将“*.*”扩展为文件名列表,并将扩展的文件名列表传递给grep等程序。 grep程序本身不会扩展文件名。

所以,回答你的问题:grep没有得到2个论点; shell将“*.*”转换为grep可以理解的内容。

GNU grep与Unix grep的不同之处在于支持额外选项,例如-w-B以及-A

在我看来,FreeBSD使用GNU版grep

答案 3 :(得分:2)

grep如何看到通配符参数取决于你的shell。 (标准)Bourne shell有一个开关(-f)来禁用文件名globbingsee man pages)。

您可以使用

在脚本中激活此开关
set -f