grep 是一个很常见也很常用的命令,他最重要的功能就是进行字串数据的比对,然后将符合使用者需求的字串列印出来。 需要说明的是『grep 在数据中查寻一个字串时,是以 "整行"为单位来进行数据的撷取的!』
1. grep -A5 -B1 --color=auto kidding regular_express.txt
我们在搜索某些关键字的时候,往往还想看看它的上下文是什么,但是之前一直不晓得grep有这个用法,今天才知道,原来就是这个-A和-B
-A 后面可加数字,为 after的意思,除了列出该行外,后续的n行也列出来;
-B 后面可加数字,为 befer 的意思,除了列出该行外,前面的n行也列出来;
--color=auto 可将正确的那个撷取数据用颜色显示
如果每次使用 grep 都得要自行加上 --color=auto 又显的很麻烦~ 此时那个好用的 alias就得来处理一下啦!你可以在 ~/.bashrc 内加上这行:
alias grep='grep --color=auto'再以source ~/.bashrc来立即生效即可,这样每次运行 grep 他都会自动帮你加上颜色显示啦~
2. 用dmesg显示核心信息,再进行搜索~
小节:
需要特别注意的是Windows系统下编辑的文件,并且已经特殊处理过,因此,他虽然是纯文字档,但是内含一些 Windows系统下的软件常常自行加入的一些特殊字节,例如断行字节 (^M)就是一例!
例题一:搜寻特定字串
grep -n 'the' regular_express.txt
grep -vn 'the' regular_express.txt
grep -in 'the' regular_express.txt
例题二:利用中括号 [] 来搜寻集合字节
grep -n 't[ae]st' regular_express.txt
grep -n 'oo' regular_express.txt
grep -n '[^g]oo' regular_express.txt【至于第三个为何会出现goooooogle,是因为 goooooogle 里面的 oo 前面可能是 o ,例如: go(ooo)oogle,所以,这一行也是符合需求的!】
假设我 oo 前面不想要有小写字节,那么我们可以这样写:
grep -n '[^a-z]oo'regular_express.txt【因为小写字节的ASCII 上编码的顺序是连续的】
假设我们要取得有数字的那一行,就这样:
grep -n '[0-9]' regular_express.txt
但由于考虑到语系对于编码顺序的影响,因此除了连续编码使用减号『 - 』之外, 你也可以使用如下的方法来取得前面两个测试的结果:
grep -n '[^[:lower:]]oo' regular_express.txt
grep -n '[[:digit:]]' regular_express.txt
例题三、行首与行尾字节 ^ $
grep -n '^the' regular_express.txt
grep -n '^[a-z]' regular_express.txt
grep -n '^[[:lower:]]' regular_express.txt
grep -n '^[^a-zA-Z]' regular_express.txt
命令也可以是: grep -n '^[^[:alpha:]]'regular_express.txt
注意:那个 ^ 符号,在字节集合符号(括号[])之内与之外是不同的! 在 [] 内代表『反向选择』,在 [] 之外则代表定位在行首的意义!
反过来思考,那如果我想要找出来,行尾结束为小数点 (.) 的那一行,该如何处理:
grep -n '\.$'regular_express.txt
小数点具有其他意义(底下会介绍),所以必须要使用跳脱字节(\)来加以解除其特殊意义! 不过,你或许会觉得奇怪,但是第 5~9 行最后面也是 . 啊~怎么无法列印出来? 这里就牵涉到 Windows 平台的软件对於断行字节的判断问题了!我们使用 cat -A 将第五行拿出来看, 你会发现:
假如我们想要搜索空白行,那么应该怎么表示呢?
grep -n '^$' regular_express.txt【因为只有行首跟行尾 (^$),所以,这样就可以找出空白行啦!】
再一个就是剔除空白行和#开头的行:
grep -v '^$' /etc/syslog.conf | grep -v'^#'
例题四:任意一个字节 . 与重复字节 *
我们知道万用字节 * 可以用来代表任意(0或多个)字节, 但是正规表示法并不是万用字节,两者之间是不相同的! 至于正规表示法当中的『 . 』则代表『绝对有一个任意字节』的意思!这两个符号在正规表示法的意义如下:
. (小数点):代表『一定有一个任意字节』的意思;
* (星星号):代表『重复前一个字节, 0 到无穷多次』的意思,为组合形态
grep -n 'g..d' regular_express.txt
[root@sor-sys zy]# grep -n 'g..d' regular_express.txt
7:Oh! The soup taste good.
10:The world <Happy> is the same with "glad".
『o*』代表的是:『拥有空字节或一个 o 以上的字节』, 特别注意,因为允许空字节(就是有没有字节都可以的意思),因此,『 grep -n 'o*' regular_express.txt 』将会把所有的数据都列印出来萤幕上!
同理,当我们需要『至少两个 o 以上的字串』时,就需要 ooo* ,亦即是:
[root@sor-sys zy]# grep -n 'ooo*' regular_express.txt
2:goooooogle yes!
3:Football game is not use feet only.
7:Oh! The soup taste good.
如果我想要找出 g 开头与 g 结尾的字串,当中的字节可有可无,那该如何是好?是『g*g』吗?
非也!!!正确的写法应该是g.*g【.* 就代表零个或多个任意字节】
grep -n 'g.*g' regular_express.txt【这个 .* 的RE 表示任意字节是很常见的】
如果我想要找出『任意数字』的行列呢?因为仅有数字,所以就成为
[root@sor-sys zy]# grep -n '[0-9][0-9]*'regular_express.txt
6:NO4-6 is to be this~
9:You are the best is mean you are the no. 1.
12:However, this dress is about $ 3183 dollars.
虽然使用 grep -n '[0-9]' regular_express.txt 也可以得到相同的结果, 但希望大家能够理解上面命令当中 RE 表示法的意义才好!
例题五、限定连续 RE 字符范围 {}
在上个例题当中,我们可以利用 . 与 RE 字符及 * 来配置 0 个到无限多个重复字节, 那如果我想要限制一个范围区间内的重复字节数呢?举例来说,我想要找出两个到五个 o 的连续字串,该如何作?这时候就得要使用到限定范围的字符 {} 了。 但因为 { 与 }的符号在 shell 是有特殊意义的,因此, 我们必须要使用跳脱字符 \来让他失去特殊意义才行。假设我要找到两个 o 的字串
[root@sor-sys zy]# grep -n 'o\{2\}' regular_express.txt
2:goooooogle yes!
3:Football game is not use feet only.
7:Oh! The soup taste good.
[root@sor-sys zy]# grep -n 'go\{2,5\}g'regular_express.txt
14:google is the best tools for search keyword.
[root@sor-sys zy]# grep -n 'go\{2,\}g' regular_express.txt
2:goooooogle yes!
14:google is the best tools for search keyword.
例题六:使用正则选项-E
小节:
^word grep -n '^#' regular_express.txt【搜寻行首为 # 开始的那一行,并列出行号】
word$ grep -n '!$' regular_express.txt【将行尾为 ! 的那一行列印出来,并列出行号 】
. 代表『一定有一个任意字节』的字符
grep -n 'e.e' regular_express.txt【亦即 e 与 e 中间『一定』仅有一个字节,而空白字节也是字节!】
\ 跳脱字符,将特殊符号的特殊意义去除!
grep -n \' regular_express.txt【搜寻含有单引号 ' 的那一行!】
* 重复零个到无穷多个的前一个 RE 字符
grep -n 'ess*' regular_express.txt【任意字节则为 『.*』 !】
[list] grep -n 'g[ld]' regular_express.txt【字节集合的 RE 字符,里面列出想要撷取的字节!在 [ ] 当中『仅代表一个待搜寻的字节』】
[n1-n2] grep -n '[A-Z]' regular_express.txt【字节集合的 RE 字符,里面列出想要撷取的字节范围!】
[^list] grep -n 'oo[^t]' regular_express.txt【字节集合的 RE 字符,里面列出不要的字串或范围!】
\{n,m\} grep -n 'go\{2,3\}g'regular_express.txt
意义:连续 n 到 m 个的『前一个 RE 字符』
意义:若为 \{n\} 则是连续 n 个的前一个 RE 字符,
意义:若是 \{n,\} 则是连续 n 个以上的前一个 RE 字符
[root@sor-sys zy]# grep 'g[ld]' regular_express.txt 【仔细看哦~】
goooooogle yes!
The world <Happy> is the same with "glad".
google is the best tools for search keyword.
glde
gdle
gldhahgld
再次强调:『正规表示法的特殊字节』与一般在命令列输入命令的『万用字节』并不相同, 例如,在万用字节当中的 * 代表的是『 0 ~ 无限多个字节』的意思,但是在正规表示法当中, * 则是『重复 0 到无穷多个的前一个 RE 字符』的意思~使用的意义并不相同,不要搞混了!
举例来说,不支持正规表示法的 ls 这个工具中,若我们使用 『ls -l * 』 代表的是任意档名的文件,而 『ls -l a* 』代表的是以 a 为开头的任何档名的文件, 但在正规表示法中,我们要找到含有以 a 为开头的文件,则必须要这样:(需搭配支持正规表示法的工具)【ls | grep -n'^a.*' 】
Q: 以 ls -l 配合 grep 找出 /etc/ 底下文件类型为连结档属性的档名
A: 由于ls -l 列出连结档时标头会是『 lrwxrwxrwx 』,因此使用如下的命令即可找出结果:
ls -l /etc | grep '^l'
若仅想要列出几个文件,再以『 |wc -l 』来累加处理即可。
两外再补充一个:
[oracle@Test230 ~]$ tail application.log |grep -q 10.1.3.3.1 && echo "[Deploy Result]:YES]" || echo "[Deploy Result]:NO"
[Deploy Result]:NO
若要是批量杀掉某个进程,可以使用以下方法打印命令:
ps -ef|grep -E "Djava.util.logging.config.file|memcached|nginx" |grep -v grep|awk '{print "kill -9",$2}'
输出结果:
kill -9 9496
kill -9 24637