69.三剑客之grep
1:grep参数:
1.参数
grep [option] pattern file # 格式
-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”参数相同。
2.grep例子
例子
1.
[root@lala test]# cat cpu.txt
Batman
manic
man
[root@lala test]# grep 'man' cpu.txt # 只要有都匹配
Batman
manic
man
[root@lala test]# grep '^man' cpu.txt # 只匹配开头是man的
manic
man
[root@lala test]# grep '^man$' cpu.txt # 只匹配man单词
man
^M 以M开头的行,^表示开始的意思
M$ 以M结尾的行,$表示结束的意思
^[0-9] 以数字开始的行,[]内可列举字母
^[124ab] 以1,2,4,a,或b开头的行
^b.503 句点表示任一字母
* 星号表示0个以上的字母(可以没有)
+ 加号表示1个以上的字母
. 斜线可以去掉特殊意义
2.查找指定进程
[root@lala test]# ps -ef|grep python
root 1205 1 0 09:54 ? 00:00:00 /usr/bin/python2 -Es /usr/sbin/tuned -l -P
root 2476 2327 0 11:03 pts/0 00:00:00 grep --color=auto python
[root@lala test]# ps -ef|grep -c python
2
3.从文件中读取关键词进行搜索,默认是显示的是行
[root@lala test]# cat cpu.txt |grep man -n
1:Batman
2:manic
3:man
4.多文件过滤内容
[root@lala test]# cd /etc/sysconfig/network-scripts/
[root@lala network-scripts]# grep "IPADDR" ifcfg-ens33 ifcfg-lo
ifcfg-ens33:IPADDR=10.20.70.222
ifcfg-lo:IPADDR=127.0.0.1
[root@lala network-scripts]# grep -f ifcfg-ens33 ifcfg-lo # 输出文件相同行内容
ONBOOT=yes
[root@lala network-scripts]# grep -of ifcfg-ens33 ifcfg-lo # -o只显示匹配到的行
ONBOOT=yes
5. 只显示过滤内容
[root@lala network-scripts]# grep 'root' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@lala network-scripts]# grep 'root' -o /etc/passwd # 只显示匹配到的字符串
root
root
root
root
[root@lala network-scripts]# grep 'root.*0' -o /etc/passwd # 配合正则使用:建议
root:x:0:0
[root@lala network-scripts]# grep 'root' -ob /etc/passwd # -b配合-o显示匹配字符串出现的开始位置
0:root
11:root
17:root
366:root
6.忽略大小写匹配
[root@lala test]# grep -i "man" cpu.txt
Batman
manic
man
Man
7.多文件匹配
[root@lala test]# grep 'n' cpu.txt a.py # 最前面会加上文件名
cpu.txt:Batman
cpu.txt:manic
cpu.txt:man
cpu.txt:Man
a.py:#!python3
a.py: print("1")
8.取反操作,不显示匹配字符行
[root@lala test]# grep -v 'man' cpu.txt # 将为匹配到的行显示出来
Man
hello
python
django
9.不显示grep本身进程
[root@lala test]# ps -ef|grep [s]shd
root 2321 1 0 10:00 ? 00:00:00 /usr/sbin/sshd -D
root 2323 2321 0 10:00 ? 00:00:00 sshd: root@pts/0
ps aux | grep ssh | grep -v "grep" #不包含grep ssh这条命令
grep -v root /etc/passwd | grep -v nologin #将/etc/passwd,将没有出现 root 和nologin的行取出来
10.递归查找
[root@lala test]# grep -r 'ab' * # 递归查找子文件中是否包含过滤内容
a/a/file1:abc
[root@lala test]# grep -rl 'ab' * #在当前目录及其子目录下搜索'ab'行的文件,但是不显示匹配的行,只显示匹配的文件
a/a/file1
duowenjian.zip
[root@lala test]# grep -nr 'ab' * # 查找子目录,匹配后输出行号,这里的点表示当前目录
a/a/file1:1:abc
[root@lala test]# grep -nr 'ab' --exclude-dir=a # 排除a目录,不进行查找a目录
Binary file duowenjian.zip matches
11.范围显示
[root@lala test]# grep -A 3 'root' /etc/passwd # 列出关键字所在行的前几行与后几行也一起显示
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
-A n 后n行,A记忆为(After)
-B n 前n行,B记忆为(Before)
-C n 前n行,后n行,C记忆为(Center)
12.动态文件
有一个文件是动态的,它不断地添加信息到文件的尾部,而你想要输出包含某些信息的行。即持续的grep一个动态的流
[root@lala test]# grep "max" --line-buffered cpu.txt
maxhope
3.grep例子2
1.e 与 E
[root@lala test]# netstat -an|grep 'ESTABLISHED|WAIT' # 默认不支持扩展正则
[root@lala test]# netstat -an|grep -E 'ESTABLISHED|WAIT' # 使用-E参数开启扩展正则
tcp 0 0 10.20.70.222:22 10.20.70.1:13683 ESTABLISHED
tcp 0 36 10.20.70.222:22 10.20.70.1:12231 ESTABLISHED
[root@lala test]# ps -ef|grep -e udevd -e master|awk '{print $(NF)}'|sort|uniq # 每个-e指定一个条件
master
/usr/lib/systemd/systemd-udevd
-w
grep -E '123|abc' filename // 找出文件(filename)中包含123或者包含abc的行
egrep '123|abc' filename // 用egrep同样可以实现
awk '/123|abc/' filename // awk 的实现方式
[root@lala test]# grep "root" /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@lala test]# grep "root" /etc/passwd |grep "nologin" # 多次过滤
operator:x:11:0:operator:/root:/sbin/nologin
2. 统计行数
[root@lala test]# grep "root" /etc/passwd -c
2
[root@lala test]# grep "nologin" /etc/passwd -c
16
3.只匹配几个
[root@lala test]# grep -m 2 'man' cpu.txt # 匹配两个之后退出
Batman
manic
4.grep配合正则使用
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或\< # 锚定单词的词首。如"\blike"不会匹配alike,但是会匹配liker
\b或\> # 锚定单词的词尾。如"\blike\b"不会匹配alike和liker,只会匹配like
\B : # 与\b作用相反。
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)
5.grep正则例子
1. ^字符
[root@lala test]# ls -l |grep '^d' # 匹配以d开头的
drwxr-xr-x. 3 root root 15 Jun 23 16:25 a
[root@lala test]# ls -l |grep '[^d]' # 在[]内表示取反,不以d开头的
total 2408
drwxr-xr-x. 3 root root 15 Jun 23 16:25 a
-rwxr-xr-x. 1 root root 71 Jun 28 15:39 a.py
-rw-r--r--. 1 root root 722 Jun 23 16:20 a.zip
-rw-r--r--. 1 root root 50 Jul 8 11:33 cpu.txt
-rw-r--r--. 1 root root 2446151 Jun 23 16:18 duowenjian.zip
-rw-------. 1 root root 112 Jun 28 15:41 nohup.out
[root@lala test]# grep -n "^$" cpu.txt # 过滤空行
6:
8:
[root@lala test]# grep 'man$' cpu.txt # 输出以man结尾的行
Batman
man
[root@lala test]# grep 'man$' cpu.txt a.py # 多文件过滤
cpu.txt:Batman
cpu.txt:man
2.匹配连续的字符
$ 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 #只输出行尾结束为小数点 (.) 的那一行
[root@lala test]# grep -E "[a-z]{5}" cpu.txt #匹配连写五个小写字符
Batman
manic
hello
3.|匹配多元素
[root@lala test]# grep -E "man|py" cpu.txt #匹配包含man或者py的行
Batman
manic
man
python
4.正则后项引用前项
[root@lala test]# grep -E 'he(llo).*\1' cpu.txt #小括号中匹配到的内容,被\1引用,既就是匹配hello.*llo
hello****hello
5.显示当前目录下面以.txt 结尾的文件中的所有包含每个字符串至少有7个连续小写字符的字符串的行
命令:grep '[a-z]{7,}' *.txt
6.查询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 -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
7.任意一个字节 . 与重复字节 *
. (小数点):代表『一定有一个任意字节』的意思;
* (星号):代表『重复前一个字符, 0 到无穷多次』的意思,为组合形态
$ grep -n '[0-9][0-9]*' regular_express.txt #找出『任意数字』的行
$ grep -n 'g.*g' regular_express.txt #找出以g行首与行尾的行,当中的字符可有可无
这个 .* 的 RE 表示任意字符是很常见的.
8.限定连续 RE 字符范围 {}
利用 . 与 RE 字符及 * 来配置 0 个到无限多个重复字节
打算找出两个到五个 o 的连续字串,该如何作?这时候就得要使用到限定范围的字符 {} 了
$ 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
参考:
https://blog.csdn.net/llljjlj/article/details/89810340
http://www.zsythink.net/archives/1733

浙公网安备 33010602011771号