目录
五、sed、awk、grep三剑客默认所使用的正则表达式类型
一、GREP基础
1.1 grep的全称
global search expression and print,全局搜索正则表达式并打印输出。
用于查找内容包含指定范本样式的文件。grep指令会把含有范本样式的那一行显示出来。而这个范本样式也就是我们在sed中所说的模式,模式可以是正则表达式也可以是普通的模式。
1.2 grep语法格式
grep OPTIONS PATTERN INPUT_FILE_NAMES
-
OPTIONS:指定0至多个
- PATTERN:即为模式,前面没有-e PATTERN或-f FILE时指定的PATTERN才会被grep识别。否则紧跟在-e选项或者-f选项后面的才会被grep程序识别成PATTERN,而除此之外的PATTERN将被错错误识别成文件名。
- INPUT_FILE_NAMES:可以指定0至多个INPUT_FILE_NAMES
#示例:过滤IP地址
[tyson@localhost ~]$ ifconfig |grep "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}"
inet 192.168.43.49 netmask 255.255.255.0 broadcast 192.168.43.255
inet6 fe80::4e92:349a:6f19:ff18 prefixlen 64 scopeid 0x20<link>
inet 127.0.0.1 netmask 255.0.0.0
二、grep常用选项
2.1 长短选项的说明
OSIX.2:便于POSIX可移植性变成。
GNU扩展的:长选项
2.2 显示常用信息
--hlep 显示常用选项
-V 显示版本
--version
2.3 控制匹配模式的选项
-e PATTERN
明确指定使用此处的PATTERN作为待匹配的PATTERN,可以指定多个。
-f FILE
从文件中获取模式列表
[tyson@localhost ~]$ ifconfig|grep -f findIp.txt
inet 192.168.43.49 netmask 255.255.255.0 broadcast 192.168.43.255
inet6 fe80::4e92:349a:6f19:ff18 prefixlen 64 scopeid 0x20<link>
inet 127.0.0.1 netmask 255.0.0.0
[tyson@localhost ~]$ cat findIp.txt
[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}
需要注意的是,若-f所指定的文件是空文件,则表示任何行都无法匹配,与awk不指定PATTERN时的情况不一样。
-i
-y
--ignore-case
忽略PATTERN的大小写(包括命令行和文件两种形式所指定的PATTERN)
[tyson@localhost ~]$ cat quote2.txt
line1
line2
line3
line4
line5
line6
line7
line8
line9
line10
line11
line12
line13
line14
[tyson@localhost ~]$ grep -i 'LINE5' quote2.txt
line5
[tyson@localhost ~]$ grep 'LINE5' quote2.txt
-v
--invert-match
翻转匹配结果,输出未匹配中的行
#输出不是ip地址的行
[tyson@localhost ~]$ ifconfig|grep -v -f findIp.txt
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 00:0c:29:d2:ca:67 txqueuelen 1000 (Ethernet)
RX packets 1956 bytes 165407 (161.5 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1333 bytes 156686 (153.0 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 68 bytes 5912 (5.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 68 bytes 5912 (5.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
-w
--word-regexp
仅选择能够精确整个单词的行:也就是单词的每一个字母必须精确匹配,不可多或少
- 何为边界:除了单词所能包含的字符外,其他字符都是分隔符,例如:空格、换行符、括号、中括号、数学运算符等。
- 何为单词:这里的单词仅由数字、字母、下划线组成。例如_word_:_不属于单词部分而是分隔符,word则是分隔符
#精确匹配单词
[tyson@localhost ~]$ echo -e 'abc\nabcc' |grep -w 'abc'
abc
-x
--line-regexp
仅选择能精确匹配整行内容的行。相当于在PTTERN中的匹配规则都变成这样了:^REGEXP$。
在下例中,第一行整行内容不是abc,所以无法匹配。而第二行的整行内容是abc,所以可以匹配。
[tyson@Tyson Lee learnGrep]$ echo -e "abcd\nabc"|grep -x "abc"
abc
[tyson@Tyson Lee learnGrep]$ echo -e "abcd\nabc"|grep "abc"
abcd
abc
[tyson@Tyson Lee learnGrep]$ echo -e "abcd\nabc"|grep "^abc$"
abc
2.4 控制输出内容的选项
-c
不再输出匹配的内容,输出匹配到的行的数量。
[tyson@Tyson Lee learnGrep]$ ifconfig |grep -f findIp.grep
inet 192.168.43.49 netmask 255.255.255.0 broadcast 192.168.43.255
inet6 fe80::4e92:349a:6f19:ff18 prefixlen 64 scopeid 0x20<link>
inet 192.168.43.179 netmask 255.255.255.0 broadcast 192.168.43.255
inet 127.0.0.1 netmask 255.0.0.0
[tyson@Tyson Lee learnGrep]$ ifconfig |grep -c -f findIp.grep
4
与-v选项结合还能输出没能成功匹配的行的数量。
[tyson@Tyson Lee learnGrep]$ ifconfig |grep -v -c -f findIp.grep
23
[tyson@Tyson Lee learnGrep]$ ifconfig |grep -v -f findIp.grep
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 00:0c:29:d2:ca:67 txqueuelen 1000 (Ethernet)
RX packets 3928 bytes 314820 (307.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 2001 bytes 247643 (241.8 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens37: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::3eae:dcdd:5ed8:5736 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:d2:ca:71 txqueuelen 1000 (Ethernet)
RX packets 1135 bytes 76281 (74.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 20 bytes 3882 (3.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
-L
不再输出匹配的内容,而是输出未能被匹配到的文件名。
在大批文件中搜索不包含某个字符串的文件。
[tyson@Tyson Lee learnGrep]$ grep -L "tyson" a.txt b.txt
b.txt
[tyson@Tyson Lee learnGrep]$ cat a.txt
tyson
[tyson@Tyson Lee learnGrep]$ cat b.txt
nginx
-l
与-L恰好相反。不再输出匹配的内容,而是输出能被匹配到的文件名,当某文件中的某行被匹配到,将不再继续向下搜索该文件。
[tyson@Tyson Lee learnGrep]$ grep -L "tyson" a.txt b.txt
a.txt
[tyson@Tyson Lee learnGrep]$ cat a.txt
tyson
[tyson@Tyson Lee learnGrep]$ cat b.txt
nginx
-m NUM
判断某个文件里面是否至少有NUM行匹配,并打印前NUM个匹配行。
[tyson@Tyson Lee learnGrep]$ grep -m 2 "line" a.txt b.txt c.txt
a.txt:line1
a.txt:line2
b.txt:line1
b.txt:line2
c.txt:line1
c.txt:line2
[tyson@Tyson Lee learnGrep]$ cat a.txt
line1
line2
line3
4
[tyson@Tyson Lee learnGrep]$ cat b.txt
line1
line2
3
4
5
6
7
[tyson@Tyson Lee learnGrep]$ cat c.txt
line1
line2
line3
line4
5
6
-o
只输出被匹配成功的字符串而不是整行。每个被匹配到的字符串都以单独的行输出。
[tyson@Tyson Lee learnGrep]$ ifconfig |grep -o -f findIp.grep
192.168.43.49
255.255.255.0
192.168.43.255
4e92:349
192.168.43.179
255.255.255.0
192.168.43.255
127.0.0.1
255.0.0.0
-q
-s
--color
不怎么常用,可以参考help中的解释。
-s, --no-messages suppress error messages
-q, --quiet, --silent suppress all normal output
--binary-files=TYPE assume that binary files are TYPE;
TYPE is 'binary', 'text', or 'without-match'
--colour[=WHEN] use markers to highlight the matching strings;
WHEN is 'always', 'never', or 'auto'
2.5 控制输出行前缀的选项
默认开启的-b -H
-b 打印从0开始的字节偏移
-H 指定了多个文件时,还需要输出匹配到的行所在的文件名。
-h
禁止输出文件名
-n
输出匹配内容在文件中的行号,每个文件都单独从1开始计数
[tyson@Tyson Lee learnGrep]$ grep -n "line" a.txt b.txt c.txt
a.txt:1:line1
a.txt:2:line2
a.txt:3:line3
b.txt:1:line1
b.txt:2:line2
c.txt:1:line1
c.txt:2:line2
c.txt:3:line3
c.txt:4:line4
不常用:-T、-Z、-u、--label=LABEL
--label=LABEL use LABEL as the standard input file name prefix
-Z, --null print 0 byte after FILE name
-u, --unix-byte-offsets report offsets as if CRs were not there
(MSDOS/Windows)
2.6 控制输出行上下文的选项
grep不会多次输出同一行
-A NUM 输出匹配到的行与匹配到的后NUM行
--after
grep -A 5 '88' filename
-B NUM 输出匹配到的行与匹配到的后NUM行
--before
-C NUM 输出上下浮动NUM 行
--context
[tyson@Tyson Lee learnGrep]$ cat /etc/passwd|grep "nobody"
nobody:x:99:99:Nobody:/:/sbin/nologin
[tyson@Tyson Lee learnGrep]$ cat /etc/passwd|grep -A 5 "nobody"
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
[tyson@Tyson Lee learnGrep]$ cat /etc/passwd|grep -B 5 "nobody"
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
[tyson@Tyson Lee learnGrep]$ cat /etc/passwd|grep -C 3 "nobody"
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
不常用--group-separato 、--no-group-separator
--group-separator=SEP use SEP as a group separator
--no-group-separator use empty string as a group separator
2.7 文件和目录的选择选项
-r
--recursive
-R
--dereference-recursive
对指定的目录进行递归搜索
[tyson@Tyson Lee ~]$ grep -r "tyson" .
./learnShell/testRead.sh:r_username="tyson"
./learnShell/tyson.sh:/home/tyson/learnShell/1.sh
./learnShell/testTest.sh:if [[ $USER == tyson* ]]
./learnShell/testTest.sh: echo "the user include str:tyson,welcome $USER."
./learnShell/testTest.sh: echo "the user don't include str:tyson,welcome,other."
Binary file ./learnShell/.testBreak.sh.swp matches
./learnShell/testFun/function_02.sh: tyson.com
./learnShell/testawk/big:tyson
./learnShell/testawk/big:tyson1
./learnShell/testawk/textChong.txt:tyson
./learnShell/testawk/textChong.txt:tyson1
./learnShell/testawk/textChong1.txt:tyson
./learnShell/testawk/textChong1.txt:tyson1
Binary file ./bzip2.tar matches
Binary file ./bin/bin.tar matches
./.viminfo: tyson
./.viminfo: [tyson@localhost ~]$ cat findIp.txt
./.viminfo:> ~/learnShell/tyson.sh
--exclude-dir=DIR
筛选出不进行递归搜索的目录,使用DIR进行匹配
[tyson@Tyson Lee ~]$ grep -r --exclude-dir="learnShell" "tyson" .
Binary file ./bzip2.tar matches
Binary file ./bin/bin.tar matches
./.viminfo: tyson
./.viminfo: [tyson@localhost ~]$ cat findIp.txt
./.viminfo:> ~/learnShell/tyson.sh
不常用
--include=FILE_PATTERN
search only files that match FILE_PATTERN
三、退出状态码
通常情况下,如果能匹配到内容,则退出状态码为0,否则为1。但是如果发生了错误,则退出状态码为2。
若使用了-s -q退出状态码不可以作为shell脚本等匹配是否成功的依据
-q
--quiet
静默模式,即使遇到了错误也不输出任何内容到标准输出。尽量避免使用该选项,通过将标准错误输出到/dev/null的形式较好。
-s
--no-messages
禁止输出因未见不存在或文件没有度权限而产生的错误输出。尽量避免使用该选项,通过将标准错误输出到/dev/null的形式较好。
四、不同的搜索引擎(不同的grep程序)
-G 是默认的grep程序,支持基本正则表达式的引擎去解析PATTERN
-E 使用扩展正则表达式的引擎,在使用上:grep -E与egrep等同。
例如:
基本正则表达式:[0-9]\{1,3\}
扩展正则表达式:[0-9]{1,3}
-F 相当于使用fgrep,是不支持任何正则表达式的grep
P 使用perl正则比到时引擎。
五、sed、awk、grep三剑客默认所使用的正则表达式类型
sed:基本正则表达式
grep:基本正则表达式
awk:扩展正则表达