grep 正则表达式及选项以及注意

说明:在原文基础上稍作了修改


grep命令简介:

在ex编辑器(我没用过)中,启动ex编辑器后要查找某个字符串时,在ex的命令提示符后键入:

:/pattern/p
:/g/pattern/p

grep这个名字就由来如此。其中p的含义是print,而当g出现在pattern前面的时候,其含义是“文件中所有行”,或“执行全局替换”。

被查找的模式称作正则表达式(regular expression)因此,把pattern换成RE,于是就成了g/RE/p,grep

grep命令语法:

前面的名字由来部分已经明确告诉我们,grep的作用是在一个或多个文件中查找茉个字符模式。egrep和fgrep都只是grep的变体,这里我们不做介绍。看一下grep的语法结构。


#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{
    int pfd[2];
    pid_t cpid;
    char buf;
    if(argc != 2)
    {
        fprintf(stderr,"Usage: %s <string>\n",argv[0]);
        exit(0);
    }
    if (pipe(pfd) == -1)
    {
        perror("pipe");
        exit(EXIT_FAILURE);
    }
    cpid = fork();
    if (cpid == -1)
    {
        perror("fork");
        exit(EXIT_FAILURE);
    }
    if (cpid == 0)
    {
        close(pfd[1]);          /* Close unused write end */
        while (read(pfd[0], &buf, 1) > 0)
            write(STDOUT_FILENO, &buf, 1);
        write(STDOUT_FILENO, "\n", 1);
        close(pfd[0]);
        exit(EXIT_SUCCESS);
    }
    else
    {
        close(pfd[0]);          /* Close unused read end */
        write(pfd[1], argv[1], strlen(argv[1]));
        close(pfd[1]);          /* Reader will see EOF */
        wait(NULL);             /* Wait for child */
        exit(EXIT_SUCCESS);
    }
}
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{
    int pfd[2];
    pid_t cpid;
    char buf;
    if(argc != 2)
    {
        fprintf(stderr,"Usage: %s <string>\n",argv[0]);
        exit(0);
    }
    if (pipe(pfd) == -1)
    {
        perror("pipe");
        exit(EXIT_FAILURE);
    }
    cpid = fork();
    if (cpid == -1)
    {
        perror("fork");
        exit(EXIT_FAILURE);
    }
    if (cpid == 0)
    {
        close(pfd[1]);          /* Close unused write end */
        while (read(pfd[0], &buf, 1) > 0)
            write(STDOUT_FILENO, &buf, 1);
        write(STDOUT_FILENO, "\n", 1);
        close(pfd[0]);
        exit(EXIT_SUCCESS);
    }
    else
    {
        close(pfd[0]);          /* Close unused read end */
        write(pfd[1], argv[1], strlen(argv[1]));
        close(pfd[1]);          /* Reader will see EOF */
        wait(NULL);             /* Wait for child */
        exit(EXIT_SUCCESS);
    }
}

grep使用的正则表达式元字符:

正则表达式中的元字符,我之前在javascript的日志中详细介绍过。这里不再解释何为正则表达式,只让大家来看一下在grep中使用的正则表达式元字符。

元字符功能示例匹配对象
^行首定位符‘^simaopig%’匹配所有以simaopig开头的行
$行尾定位符‘simaopig$’匹配所有以simaopig结尾的行
.匹配任意一个字符‘s.m’匹配包含一个s字符,后面跟一个字符(随意),再跟一个m的行
*匹配0或多个前一字符‘s*m’匹配包含零个或多个s字符,后面跟有一个m字符的行
[]匹配一组字符中的任意一个‘[Ss]imaopig’匹配simaopig,或者Simaopig
[^]匹配不在指定字符组内的字符‘[^a-z]imaopig’匹配不包含在a-z之间的字符后跟着imaopig的行,即所有aimaopig-zimaopig的行都不包含(有点绕)
\<词首定位符‘\<simaopig’匹配以simaopig为开头的词的行,simaopigabcd也是可以的
\>词尾定位符‘simaopig\>’匹配以simaopig为结尾的词的行,abcdsimaopig也是可以的
\(..\)标记匹配的字符‘\(simaopig\)'s blog’标记寄存器里的一段字符,该寄存器被记作1号寄存器。以后引用这段字符时,可以使用\1来重复该模式。9个标签中最左边的是第一号。例如,模式simaopig被保存在1号寄存器里,之后用\1来引用它。
x\{m\}或x\{m,\}或x\{m,n\}字符x的重复出现‘s\{5\}’,'s\{5,\}’,'s\{5,10\}’匹配连续出现5个s、至少5个s或5到10个s的行

grep的选项:

观其语法结构,grep有着很丰富的选项。下面的表格中我会为大家介绍其常用的选项。

选项功能
-b在每一行前面加上其所在的块号,根据上下文定位磁盘块时可能会用到
-c显示匹配到的行的数目,而不是显示行的内容
-h不显示文件名
-i比较字符时忽略大小写的区别
-l(小写的字母L)只列出匹配行所在文件的文件名(每个文件名只列一次),文件名之间用换行符分隔
-n在每一行前面加上它在文件中的相对行号
-s无声操作,即只显示报错信息,用于检查退出状态
-v反向查找,只显示不匹配的行
-w把表达式作为词来查找,就好像它被\<和\>夹着那样。只适用于grep(并非所有版本的grep都支持这一功能,譬如,SCO UNIX就不支持)

grep简单示例:

例如第一个表格中,我想查找所有带有if的行并且显示行号,如何查找呢?

grep  -n if a.html

输出:


使用过程中,使用最多的参数就是 -v ,但是用着并不爽。

比如说,我想查找一个单词“UserService”,但是像”*.svn” 这种文件就不用显示了,我该怎么做呢?

grep  -r  "UserService" . /  |  grep  -v  "svn"

但是,如果类似于含有”test、auto_load”之类的文件我也不显示,怎么做呢?我之前的做法是:

grep  -r  "UserService" . /  |  grep  -v  "svn"  |  grep  -v  "test"  |  grep  -v  "auto_load"

命令很长,而且麻烦,于是就想,grep本身是按照正则表达式来当做选项的,那么我是不是可以利用到正则表达式的“或|”命令?

grep  -r  "UserService" . /  |  grep  -v  "svn|test|auto_load"

很显示,执行结果显示上面的命令不符合我的需求,于是苦思不得其解。原来,在使用正则表达式选项时,要记得将”|”转义。最终命令如下:

grep  -r  "UserService" . /  |  grep  -v  "svn\|prj\|test\|auto_load"

声明: 本文采用 BY-NC-SA 协议进行授权 | 小小子
转载转自《grep 正则表达式及选项》和grep 正则表达式选项要记得转义

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值