LinuxShell脚本⼊门--grep命令详解
grep简介< 摘⾃鸟哥,并加以整理。 >
grep (global search regular expression(RE) and print out the line,全⾯搜索正则表达式并把⾏打印出来)是⼀种强⼤的⽂本搜索⼯具,它能使⽤正则表达式搜索⽂本,并把匹配的⾏打印出来。
Unix的grep家族包括grep、egrep和fgrep。egrep和fgrep的命令只跟grep有很⼩不同。egrep是grep的扩展,⽀持更多的re元字符,fgrep就是fixed grep或fast grep,它们把所有的字母都看作单词,也就是说,正则表达式中的元字符表⽰回其⾃⾝的字⾯意义,不再特殊。linux使⽤GNU版本的grep。它功能更强,可以通过-G、-E、-F命令⾏选项来使⽤egrep和fgrep的功能。
常⽤的g r e p选项有:
-c 只输出匹配⾏的计数。
-i 不区分⼤⼩写(只适⽤于单字符)。
-h 查询多⽂件时不显⽰⽂件名。
-l 查询多⽂件时只输出包含匹配字符的⽂件名。
-n 显⽰匹配⾏及⾏号。
-s 不显⽰不存在或⽆匹配⽂本的错误信息。
-v 显⽰不包含匹配⽂本的所有⾏。
将/etc/passwd,有出现 root 的⾏取出来:
# grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
将/etc/passwd,有出现 root 的⾏取出来,同时显⽰这些⾏在/etc/passwd的⾏号:
# grep -n root /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
30:operator:x:11:0:operator:/root:/sbin/nologin
⽤ dmesg 列出核⼼信息,再以 grep 出内含 eth 那⾏,要将捉到的关键字显⾊,且加上⾏号来表⽰:
[root@www ~]# dmesg | grep -n --color=auto 'eth'
247:eth0: RealTek RTL8139 at 0xee846000, 00:90:cc:a6:34:84, IRQ 10
248:eth0: Identified 8139 chip type 'RTL-8139C'
294:eth0: link up, 100Mbps, full-duplex, lpa 0xC5E1
305:eth0: no IPv6 routers present
# 你会发现除了 eth 会有特殊颜⾊来表⽰之外,最前⾯还有⾏号喔!
在关键字的显⽰⽅⾯,grep 可以使⽤ --color=auto 来将关键字部分使⽤颜⾊显⽰。 这可是个很不错的功能啊!但是如果每次使⽤ grep 都得要⾃⾏加上 --color=auto ⼜显的很⿇烦~ 此时那个好⽤的 alias 就得来处理⼀下啦!你可以在 ~/.bashrc 内加上这⾏:『alias grep='grep --color=auto'』再以『 source ~/.bashrc 』来⽴即⽣效即可喔! 这样每次运⾏ grep 他都会⾃动帮你加上颜⾊显⽰啦
⽤ dmesg 列出核⼼信息,再以 grep 出内含 eth 那⾏,在关键字所在⾏的前两⾏与后三⾏也⼀起捉出来显⽰:
[root@www ~]# dmesg | grep -n -A3 -B2 --color=auto 'eth'
245-PCI: setting IRQ 10 as level-triggered
246-ACPI: PCI Interrupt 0000:00:0e.0[A] -> Link [LNKB] ...
247:eth0: RealTek RTL8139 at 0xee846000, 00:90:cc:a6:34:84, IRQ 10
248:eth0: Identified 8139 chip type 'RTL-8139C'
249-input: PC Speaker as /class/input/input2
250-ACPI: PCI Interrupt 0000:00:01.4[B] -> Link [LNKB] ...
251-hdb: ATAPI 48X DVD-ROM DVD-R-RAM CD-R/RW drive, 2048kB Cache, UDMA(66)
# 如上所⽰,你会发现关键字 247 所在的前两⾏及 248 后三⾏也都被显⽰出来!
# 这样可以让你将关键字前后数据捉出来进⾏分析啦!
根据⽂件内容递归查⽬录:
# grep ‘energywise’ * #在当前⽬录搜索带'energywise'⾏的⽂件
# grep -r ‘energywise’ * #在当前⽬录及其⼦⽬录下搜索'energywise'⾏的⽂件
# grep -l -r ‘energywise’ * #在当前⽬录及其⼦⽬录下搜索'energywise'⾏的⽂件
这⼏个命令很使⽤,是查⽂件的利器。
grep与正规表达式
字符类
字符类的搜索:如果我想要搜寻 test 或 taste 这两个单字时,可以发现到,其实她们有共通的 't?st' 存在~这个时候,我可以这样来搜寻:
[root@www ~]# grep -n 't[ae]st'
8:I can't finish the test.
9:Oh! The soup taste good.
其实 [] ⾥⾯不论有⼏个字节,他都谨代表某『⼀个』字节, 所以,上⾯的例⼦说明了,我需要的字串是『tast』或『test』两个字串⽽已!
字符类的反向选择 [^] :如果想要搜索到有 oo 的⾏,但不想要 oo 前⾯有 g,如下
[root@www ~]# grep -n '[^g]oo'
2:apple is my favorite food.
3:Football game is not use feet only.
18:google is the best tools for search keyword.
19:goooooogle yes!
第 2,3 ⾏没有疑问,因为 foo 与 Foo 均可被接受!
但是第 18 ⾏明明有 google 的 goo 啊~别忘记了,因为该⾏后⾯出现了 tool 的 too 啊!所以该⾏也被列出来~ 也就是说, 18 ⾏⾥⾯虽然出现了我们所不要的项⽬ (goo) 但是由於有需要的项⽬ (too) , 因此,是符合字串搜寻的喔!
⾄於第 19 ⾏,同样的,因为 goooooogle ⾥⾯的 oo 前⾯可能是 o ,例如: go(ooo)oogle ,所以,这⼀⾏也是符合需求的!
字符类的连续:再来,假设我 oo 前⾯不想要有⼩写字节,所以,我可以这样写 [^]oo , 但是这样似乎不怎么⽅便,由於⼩写字节的 ASCII 上编码的顺序是连续的, 因此,我们可以将之简化为底下这样:
[root@www ~]# grep -n '[^a-z]oo'
3:Football game is not use feet only.
也就是说,当我们在⼀组集合字节中,如果该字节组是连续的,例如⼤写英⽂/⼩写英⽂/数字等等, 就可以使⽤[a-z],[A-Z],[0-9]等⽅式来书写,那么如果我们的要求字串是数字与英⽂呢? 呵呵!就将他全部写在⼀起,变成:[a-zA-Z0-9]。
我们要取得有数字的那⼀⾏,就这样:
[root@www ~]# grep -n '[0-9]'
5:However, this dress is about $ 3183 dollars.
15:You are the best is mean you are the no. 1.
⾏⾸与⾏尾字节 ^ $
⾏⾸字符:如果我想要让 the 只在⾏⾸列出呢? 这个时候就得要使⽤定位字节了!我们可以这样做:
[root@www ~]# grep -n '^the'
12:the symbol '*' is represented as start.
此时,就只剩下第 12 ⾏,因为只有第 12 ⾏的⾏⾸是 the 开头啊~此外, 如果我想要开头是⼩写字节的那⼀⾏就列出呢?可以这样:
[root@www ~]# grep -n '^[a-z]'
2:apple is my favorite food.
4:this dress doesn't fit me.
10:motorcycle is cheap than car.
12:the symbol '*' is represented as start.
18:google is the best tools for search keyword.
19:goooooogle yes!
20:go! go! Let's go.
如果我不想要开头是英⽂字母,则可以是这样:
[root@www ~]# grep -n '^[^a-zA-Z]'
1:"Open Source" is a good mechanism to develop programs.
21:# I am VBird
^ 符号,在字符类符号(括号[])之内与之外是不同的! 在 [] 内代表『反向选择』,在 [] 之外则代表定位在⾏⾸的意义!
那如果我想要出来,⾏尾结束为⼩数点 (.) 的那⼀⾏:
[root@www ~]# grep -n '\.$'
1:"Open Source" is a good mechanism to develop programs.
2:apple is my favorite food.
3:Football game is not use feet only.
4:this dress doesn't fit me.
10:motorcycle is cheap than car.
11:This window is clear.
12:the symbol '*' is represented as start.
15:You are the best is mean you are the no. 1.
16:The world <Happy> is the same with "glad".
17:I like dog.
18:google is the best tools for search keyword.
20:go! go! Let's go.
特别注意到,因为⼩数点具有其他意义(底下会介绍),所以必须要使⽤转义字符(\)来加以解除其特殊意义!
出空⽩⾏:
[root@www ~]# grep -n '^$'
22:
因为只有⾏⾸跟⾏尾 (^$),所以,这样就可以出空⽩⾏啦!
任意⼀个字节 . 与重复字节 *
这两个符号在正则表达式的意义如下:
. (⼩数点):代表『⼀定有⼀个任意字节』的意思;
* (星号):代表『重复前⼀个字符,0到⽆穷多次』的意思,为组合形态
假设我需要出 g??d 的字串,亦即共有四个字节, 起头是 g ⽽结束是 d ,我可以这样做:
[root@www ~]# grep -n 'g..d'
1:"Open Source" is a good mechanism to develop programs.
9:Oh! The soup taste good.
16:The world <Happy> is the same with "glad".
因为强调 g 与 d 之间⼀定要存在两个字节,因此,第 13 ⾏的 god 与第 14 ⾏的 gd 就不会被列出来啦!
如果我想要列出有 oo, ooo, oooo 等等的数据, 也就是说,⾄少要有两个(含) o 以上,该如何是好?
因为 * 代表的是『重复 0 个或多个前⾯的 RE 字符』的意义, 因此,『o*』代表的是:『拥有空字节或⼀个 o 以上的字节』,因此,『grep -n 'o*' 』将会把所有的数据都列印出来终端上!
当我们需要『⾄少两个 o 以上的字串』时,就需要 ooo* ,亦即是:
[root@www ~]# grep -n 'ooo*'
linux命令及shell编写1:"Open Source" is a good mechanism to develop programs.
2:apple is my favorite food.
3:Football game is not use feet only.
9:Oh! The soup taste good.
18:google is the best tools for search keyword.
19:goooooogle yes!
如果我想要字串开头与结尾都是 g,但是两个 g 之间仅能存在⾄少⼀个 o ,亦即是 gog, goog, 等等,那该如何?
[root@www ~]# grep -n 'goo*g'
18:google is the best tools for search keyword.
19:goooooogle yes!
如果我想要出 g 开头与 g 结尾的⾏,当中的字符可有可⽆
[root@www ~]# grep -n 'g.*g'
1:"Open Source" is a good mechanism to develop programs.
14:The gd software is a library for drafting programs.
18:google is the best tools for search keyword.
19:goooooogle yes!
20:go! go! Let's go.
因为是代表 g 开头与 g 结尾,中间任意字节均可接受,所以,第 1, 14, 20 ⾏是可接受的喔! 这个 .* 的 RE 表⽰任意字符是很常见的.
如果我想要出『任意数字』的⾏?因为仅有数字,所以就成为:
[root@www ~]# grep -n '[0-9][0-9]*'
5:However, this dress is about $ 3183 dollars.
15:You are the best is mean you are the no. 1.
限定连续 RE 字符范围 {}
我们可以利⽤ . 与 RE 字符及 * 来配置 0 个到⽆限多个重复字节, 那如果我想要限制⼀个范围区间内的重复字节数呢?
举例来说,我想要出两个到五个 o 的连续字串,该如何作?这时候就得要使⽤到限定范围的字符 {} 了。 但因为 { 与 } 的符号在 shell 是有特殊意义的,因此, 我们必须要使⽤字符 \ 来让他失去特殊意义才⾏。 ⾄於 {} 的语法是这样的,假设我要到两个 o 的字串,可以是:
[root@www ~]# grep -n 'o\{2\}'
1:"Open Source" is a good mechanism to develop programs.
2:apple is my favorite food.
3:Football game is not use feet only.
9:Oh! The soup taste good.
18:google is the best tools for search ke
19:goooooogle yes!
假设我们要出 g 后⾯接 2 到 5 个 o ,然后再接⼀个 g 的字串,他会是这样:
[root@www ~]# grep -n 'go\{2,5\}g'
18:google is the best tools for search keyword.
如果我想要的是 2 个 o 以上的 呢?除了可以是 gooo*g ,也可以是:
[root@www ~]# grep -n 'go\{2,\}g'
18:google is the best tools for search keyword.
19:goooooogle yes!
扩展grep(grep -E 或者 egrep):
使⽤扩展grep的主要好处是增加了额外的正则表达式元字符集。
打印所有包含NW或EA的⾏。如果不是使⽤egrep,⽽是grep,将不会有结果查出。
# egrep'NW|EA' testfile
northwest NW Charles Main 3.0 .98334
eastern EA TB Savage 4.4 .84520
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论