Linux grep 命令用于查找文件里符合条件的字符串。
grep 指令用于查找内容包含指定的范本样式的文件,如果发现某文件的内容符合所指定的范本样式,预设 grep 指令会把含有范本样式的那一列显示出来。若不指定任何文件名称,或是所给予的文件名为 -,则 grep 指令会从标准输入设备读取数据。
语法
grep [-abcEFGhHilLnqrsvVwxy][-A<显示列数>][-B<显示列数>][-C<显示列数>][-d<进行动作>][-e<范本样式>][-f<范本文件>][—help][范本样式][文件或目录…]
grep命令用于搜索由Pattern参数指定的模式,
并将每个匹配的行写入标准输出中。这些模式是具有限定的正则表达式,
它们使用ed或egrep命令样式。如果在File参数中指定了多个名称,
grep命令将显示包含匹配行的文件的名称。
对 shell 有特殊含义的字符 ($, *, [, |, ^, (, ), \ ) 出现在 Pattern参数中时必须带双引号。
如果 Pattern参数不是简单字符串,通常必须用单引号将整个模式括起来。
在诸如 [a-z], 之类的表达式中,-(减号)cml 可根据当前正在整理的序列来指定一个范围。
整理序列可以定义等价的类以供在字符范围中使用。如果未指定任何文件,grep会假定为标准输入。
**
grep正则表达式元字符集(基本集)
^ 锚定行的开始 如:'^grep'匹配所有以grep开头的行。
$ 锚定行的结束 如:'grep$'匹配所有以grep结尾的行。
. 匹配一个非换行符的字符 如:'gr.p'匹配gr后接一个任意字符,然后是p。
* 匹配零个或多个先前字符 如:' *grep'匹配所有一个或多个空格后紧跟grep的行。
.*一起用代表任意字符。
[] 匹配一个指定范围内的字符,如'[Gg]rep'匹配Grep和grep。
[^] 匹配一个不在指定范围内的字符,如:'[^A-FH-Z]rep'匹配不包含A-F和H-Z的一个字母开头,
紧跟rep的行。
\(..\) 标记匹配字符,如:'\(love\)',love被标记为1。
\< 锚定单词的开始,如:'\<grep'匹配包含以grep开头的单词的行。
\> 锚定单词的结束,如'grep\>'匹配包含以grep结尾的单词的行。
x\{m\} 连续重复字符x,m次,如:'o\{5\}'匹配包含连续5个o的行。
x\{m,\} 连续重复字符x,至少m次,如:'o\{5,\}'匹配至少连续有5个o的行。
x\{m,n\} 连续重复字符x,至少m次,不多于n次,如:'o\{5,10\}'匹配连续5--10个o的行。
\w 匹配一个文字和数字字符,也就是[A-Za-z0-9],如:'G\w*p'匹配以G后跟零个或多个文字或数字字符,
然后是p。
\W w的反置形式,匹配一个非单词字符,如点号句号等。\W*则可匹配多个。
\b 单词锁定符,如: '\bgrep\b'只匹配grep,即只能是grep这个单词,两边均为空格。
grep的常用选项:
-V: 打印grep的版本号
-E: 解释PATTERN作为扩展正则表达式,也就相当于使用egrep
-F : 解释PATTERN作为固定字符串的列表,由换行符分隔,其中任何一个都要匹配。
也就相当于使用fgrep。
-G: 将范本样式视为普通的表示法来使用。这是默认值。加不加都是使用grep。
匹配控制选项:
-e : 使用PATTERN作为模式。这可以用于指定多个搜索模式,或保护以连字符( - )开头的图案。
指定字符串做为查找文件内容的样式。
-f : 指定规则文件,其内容含有一个或多个规则样式,让grep查找符合规则条件的文件内容,
格式为每行一个规则样式。
-i : 搜索时候忽略大小写
-v: 反转匹配,选择没有被匹配到的内容。
-w:匹配整词,精确地单词,单词的两边必须是非字符符号(即不能是字母数字或下划线)
-x:仅选择与整行完全匹配的匹配项。精确匹配整行内容
(包括行首行尾那些看不到的空格内容都要完全匹配)
-y:此参数的效果和指定“-i”参数相同。
一般输出控制选项:
-c: 抑制正常输出;而是为每个输入文件打印匹配线的计数。
--color [= WHEN]:让关键字高亮显示,如--color=auto
-L:列出文件内容不符合指定的范本样式的文件名称
-l : 列出文件内容符合指定的范本样式的文件名称。
-m num:当匹配内容的行数达到num行后,grep停止搜索,并输出停止前搜索到的匹配内容
-o: 只输出匹配的具体字符串,匹配行中其他内容不会输出
-q:安静模式,不会有任何输出内容,查找到匹配内容会返回0,未查找到匹配内容就返回非0
-s:不会输出查找过程中出现的任何错误消息,-q和-s选项因为与其他系统的grep有兼容问题,
shell脚本应该避免使用-q和-s,并且应该将标准和错误输出重定向到/dev/null 代替。
输出线前缀控制:
-b:输出每一个匹配行(或匹配的字符串)时在其前附加上偏移量(从文件第一个字符到该匹配内容之间的字节数)
-H:在每一个匹配行之前加上文件名一起输出(针对于查找单个文件),当查找多个文件时默认就会输出文件名
-h:禁止输出上的文件名的前缀。无论查找几个文件都不会在匹配内容前输出文件名
--label = LABEL:显示实际来自标准输入的输入作为来自文件LABEL的输入。这是特别在实现zgrep等工具时非常有用,例如gzip -cd foo.gz | grep --label = foo -H的东西。看到 也是-H选项。
-n:输出匹配内容的同时输出其所在行号。
-T:初始标签确保实际行内容的第一个字符位于制表位上,以便对齐标签看起来很正常。在匹配信息和其前的附加信息之间加入tab以使格式整齐。
上下文线控制选项:
-A num:匹配到搜索到的行以及该行下面的num行
-B num:匹配到搜索到的行以及该行上面的num行
-C num:匹配到搜索到的行以及上下各num行
文件和目录选择选项:
-a: 处理二进制文件,就像它是文本;这相当于--binary-files = text选项。不忽略二进制的数据。
--binary-files = TYPE:如果文件的前几个字节指示文件包含二进制数据,则假定该文件为类型TYPE。
默认情况下,TYPE是二进制的,grep通常输出一行消息二进制文件匹配,或者如果没有匹配则没有消息。
如果TYPE不匹配,grep假定二进制文件不匹配;这相当于-I选项。如果TYPE是文本,则grep处理a二进制文件,如果它是文本;这相当于-a选项。警告:grep --binary-files = text可能会输出二进制的垃圾,如果输出是一个终端和如果可能有讨厌的副作用终端驱动程序将其中的一些解释为命令。
-D:如果输入文件是设备,FIFO或套接字,请使用ACTION处理。默认情况下,读取ACTION,
这意味着设备被读取,就像它们是普通文件一样。如果跳过ACTION,设备为 默默地跳过。
-d: 如果输入文件是目录,请使用ACTION处理它。默认情况下,ACTION是读的,这意味着目录被读取,
就像它们是普通文件一样。如果跳过ACTION,目录将静默跳过。如果ACTION是recurse,grep将递归读取每个目录下的所有文件;这是相当于-r选项。
--exclude=GLOB:跳过基本名称与GLOB匹配的文件(使用通配符匹配)。
文件名glob可以使用*,?和[...]作为通配符,和\引用通配符或反斜杠字符。
搜索其文件名和GLOB通配符相匹配的文件的内容来
查找匹配使用方法:grep -H --exclude=c* "old" ./*
c*是通配文件名的通配符./* 指定需要先通配文件名的文件的范围,
必须要给*,不然就匹配不出内容,(如果不给*,带上-r选项也可以匹配)
--exclude-from = FILE:在文件中编写通配方案,grep将不会到匹配方案中文件名的文件去查找匹配内容
--exclude-dir = DIR:匹配一个目录下的很多内容同时还要让一些子目录不接受匹配,就使用此选项。
--include = GLOB:仅搜索其基本名称与GLOB匹配的文件(使用--exclude下所述的通配符匹配)。
-R ,-r :以递归方式读取每个目录下的所有文件; 这相当于-d recurse选项。
其他选项:
--line-buffered: 在输出上使用行缓冲。这可能会导致性能损失。
--mmap:启用mmap系统调用代替read系统调用
-U:将文件视为二进制。
-z:将输入视为一组行,每一行由一个零字节(ASCII NUL字符)而不是a终止新队。与-Z或--null选项一样,此选项可以与排序-z等命令一起使用来处理任意文件名。
简述
-a --text #不要忽略二进制的数据。 将 binary 文件以 text 文件的方式搜寻数据
-A<显示行数> --after-context=<显示行数> #除了显示符合范本样式的那一列之外,并显示该行之后的内容。
-b --byte-offset #在显示符合样式的那一行之前,标示出该行第一个字符的编号。
-B<显示行数> --before-context=<显示行数> #除了显示符合样式的那一行之外,并显示该行之前的内容。
-c --count #计算符合样式的行数。
-C<显示行数> --context=<显示行数>或-<显示行数> #除了显示符合样式的那一行之外,并显示该行之前后的内容。
-d <动作> --directories=<动作> #当指定要查找的是目录而非文件时,必须使用这项参数,否则grep指令将回报信息并停止动作。
-e<范本样式> --regexp=<范本样式> #指定字符串做为查找文件内容的样式。
-E --extended-regexp #将样式为延伸的普通表示法来使用。
-f<规则文件> --file=<规则文件> #指定规则文件,其内容含有一个或多个规则样式,让grep查找符合规则条件的文件内容,格式为每行一个规则样式。
-F --fixed-regexp #将样式视为固定字符串的列表。
-G --basic-regexp #将样式视为普通的表示法来使用。
-h --no-filename #在显示符合样式的那一行之前,不标示该行所属的文件名称。
-H --with-filename #在显示符合样式的那一行之前,表示该行所属的文件名称。
-i --ignore-case #忽略字符大小写的差别。
-l --file-with-matches #列出文件内容符合指定的样式的文件名称。
-L --files-without-match #列出文件内容不符合指定的样式的文件名称。
-n --line-number #在显示符合样式的那一行之前,标示出该行的列数编号。
-q --quiet或--silent #不显示任何信息。
-r --recursive #此参数的效果和指定“-d recurse”参数相同。
-s --no-messages #不显示错误信息。
-v --revert-match #显示不包含匹配文本的所有行。
-V --version #显示版本信息。
-w --word-regexp #只显示全字符合的列。
-x --line-regexp #只显示全列符合的列。
-y #此参数的效果和指定“-i”参数相同。
=====
ls -l | grep ‘^a’ 通过管道过滤ls -l输出的内容,只显示以a开头的行。
grep ‘test’ d* 显示所有以d开头的文件中包含test的行。
grep ‘test’ aa bb cc 显示在aa,bb,cc文件中匹配test的行。
grep ‘[a-z]’ aa 显示所有包含每个字符串至少有5个连续小写字符的字符串的行。
grep ‘w(es)t.*’ aa 如果west被匹配,则es就被存储到内存中,并标记为1,然后搜索任意个字符(.),
这些字符后面紧跟着另外一个es(),找到就显示该行。如果用egrep或grep -E,
就不用””号进行转义,直接写成’w(es)t.‘就可以了。
grep -i pattern files :不区分大小写地搜索。默认情况区分大小写
grep -l pattern files :只列出匹配的文件名,
grep -L pattern files :列出不匹配的文件名,
grep -w pattern files :只匹配整个单词,而不是字符串的一部分(如匹配‘magic’,
而不是‘magical’),
grep -C number pattern files :匹配的上下文分别显示[number]行,
grep pattern1 | pattern2 files :显示匹配 pattern1 或 pattern2 的行,
grep pattern1 files | grep pattern2 :显示既匹配 pattern1 又匹配 pattern2 的行。
二、与正则表达式结合
grep的规则表达式:
\ 反义字符:如"\"\""表示匹配""
[ - ] 匹配一个范围,[0-9a-zA-Z]匹配所有数字和字母
* 所有字符,长度可为0
+ 前面的字符出现了一次或者多次
^ #匹配行的开始 如:'^grep'匹配所有以grep开头的行。
$ #匹配行的结束 如:'grep$'匹配所有以grep结尾的行。
. #匹配一个非换行符的字符 如:'gr.p'匹配gr后接一个任意字符,然后是p。
* #匹配零个或多个先前字符 如:'*grep'匹配所有一个或多个空格后紧跟grep的行。
.* #一起用代表任意字符。
[] #匹配一个指定范围内的字符,如'[Gg]rep'匹配Grep和grep。
[^] #匹配一个不在指定范围内的字符,如:'[^A-FH-Z]rep'匹配不包含A-R和T-Z的一个字母开头,
紧跟rep的行。
\(..\) #标记匹配字符,如'\(love\)',love被标记为1。
\< #到匹配正则表达式的行开始,如:'\<grep'匹配包含以grep开头的单词的行。
\> #到匹配正则表达式的行结束,如'grep\>'匹配包含以grep结尾的单词的行。
x\{m\} #重复字符x,m次,如:'0\{5\}'匹配包含5个o的行。
x\{m,\} #重复字符x,至少m次,如:'o\{5,\}'匹配至少有5个o的行。
x\{m,n\} #重复字符x,至少m次,不多于n次,如:'o\{5,10\}'匹配5--10个o的行。
\w #匹配文字和数字字符,也就是[A-Za-z0-9],如:'G\w*p'匹配以G后跟零个或多个文字或数字字符,
然后是p。
\W #\w的反置形式,匹配一个或多个非单词字符,如点号句号等。
\b #单词锁定符,如: '\bgrep\b'只匹配grep。
POSIX字符:
为了在不同国家的字符编码中保持一至,POSIX(The Portable Operating System Interface)
增加了特殊的字符类,如[:alnum:]是[A-Za-z0-9]的另一个写法。要把它们放到[]号内才能成为正则表达式,
如[A- Za-z0-9]或[[:alnum:]]。在linux下的grep除fgrep外,都支持POSIX的字符类。
[:alnum:] #文字数字字符
[:alpha:] #文字字符
[:digit:] #数字字符
[:graph:] #非空字符(非空格、控制字符)
[:lower:] #小写字符
[:cntrl:] #控制字符
[:print:] #非空字符(包括空格)
[:punct:] #标点符号
[:space:] #所有空白字符(新行,空格,制表符)
[:upper:] #大写字符
[:xdigit:] #十六进制数字(0-9,a-f,A-F)
例:通过管道过滤ls -l输出的内容,只显示以a开头的行。
首与行尾字节 ^ $,^ 符号,在字符类符号(括号[])之内与之外是不同的! 在 [] 内代表『反向选择』,在 [] 之外则代表定位在行首的意义!
$ ls -l | grep \’^a\’
$ ls -l | grep ^a
$ ls -l | grep ^[^a] #输出非a开头的行,反向选择
$ grep -n ‘^$’ express.txt #找出空白行,因为只有行首跟行尾 (^$)
例:显示所有以d开头的文件中包含test的行。
$ grep \’test\’ d
例:输出以hat结尾的行内容
$ cat test.txt |grep hat$
例:显示在aa,bb,cc文件中匹配test的行。
$ grep \’test\’ aa bb cc
例:显示所有包含每个字符串至少有5个连续小写字符的字符串的行。
在一组集合字节中,如果该字节组是连续的,例如大写英文/小写英文/数字等等,就可以使用[a-z],[A-Z],[0-9]等方式来书写,那么如果我们的要求字串是数字与英文呢?就将他全部写在一起,变成:[a-zA-Z0-9]。
$ grep \’[a-z]{5}\’ aa
$ grep -n ‘[0-9]’ regular_express.txt #取得有数字的那一行
$ grep -n ‘^[a-z]’ regular_express.txt #只输出开头是小写字母的那一行
$ grep -n ‘^[^a-zA-Z]’ regular_express.txt #不输出开头是英文的
$ grep -n ‘.$’ regular_express.txt #只输出行尾结束为小数点 (.) 的那一行
注意:小数点具有其他意义,所以必须要使用转义字符()来加以解除其特殊意义!
例:显示包含ed或者at字符的内容行
命令:cat test.txt |grep -E “ed|at”
例:如果west被匹配,则es就被存储到内存中,并标记为1,然后搜索任意个字符(.),这些字符后面紧跟着另外一个es(1),找到就显示该行。如果用egrep或grep -E,就不用””号进行转义,直接写成\’w(es)t.1\’就可以了。
$ grep \’w(es)t.1\’ aa
例:显示当前目录下面以.txt 结尾的文件中的所有包含每个字符串至少有7个连续小写字符的字符串的行
命令:grep ‘[a-z]{7}‘ .txt
例:查询IP地址、邮箱、手机号
这里用到了-o和-P命令
man grep查看
-o, —only-matching:
Show only the part of a matching line that matches PATTERN.
-P, —perl-regexp:
Interpret PATTERN as a Perl regular expression.
也就是说-o,只显示匹配行中匹配正则表达式的那部分,-P,作为Perl正则匹配
192.168.0.1
abc@163.com
匹配ABC类IP地址即 1.0.0.1—-223.255.255.254
命令(IP):grep -oP “([0-9]{1,3}.){3}[0-9]{1,3}” file.txt
或grep -E —color “\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-1][0-9]|22[0-3]).([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]).([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]).([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4])>“ file.txt
邮箱是任意长度数字字母@任意长度数字字母
命令(邮箱):grep -oP “[a-zA-Z0-9-]+@[a-zA-Z0-9-]+(.[a-zA-Z0-9_-]+)+” file.txt
手机号码是1[3|4|5|8]后面接9位数字的
命令(手机号):grep -E “\<1[3|4|5|8][0-9]{9}\>“ file.txt
例:任意一个字节 . 与重复字节
. (小数点):代表『一定有一个任意字节』的意思;
* (星号):代表『重复前一个字符, 0 到无穷多次』的意思,为组合形态
$ grep -n ‘[0-9][0-9]‘ regular_express.txt #找出『任意数字』的行
$ grep -n ‘g.g’ regular_express.txt #找出以g行首与行尾的行,当中的字符可有可无
这个 . 的 RE 表示任意字符是很常见的.
例:限定连续 RE 字符范围 {}
利用 . 与 RE 字符及 来配置 0 个到无限多个重复字节
打算找出两个到五个 o 的连续字串,该如何作?这时候就得要使用到限定范围的字符 {} 了。 但因为 { 与 } 的符号在 shell 是有特殊意义的,因此, 我们必须要使用字符 \ 来让他失去特殊意义才行。
$ grep -n ‘o{2}‘ regular_express.txt
$ grep -n ‘go{2,5}g’ regular_express.txt #要找出 g 后面接 2 到 5 个 o ,然后再接一个 g 的字串
$ grep -n ‘go{2,}g’ regular_express.txt #想要的是 2 个 o 以上的 goooo….g 呢?除了可以是 gooo*g
获取哪些文件aaa和bbb关键字都包含
grep -o “aaa” -o “bbb” -rl —include=”*.txt” /usr/local/src/
—include 用于只查找某些文件
—exclude-dir 用于排除某些文件夹
例子:
grep -rl ‘search’ ./ —exclude-dir={\environments,\cache} —exclude=*.{bak~,bak}