天天看点

linux12shell编程 --> 三剑客之grep命令

文章目录

  • ​​三剑客之grep命令​​
  • ​​一 、grep介绍​​
  • ​​1、grep命令主要用于过滤文本,grep家族如下​​
  • ​​2、grep命令格式如下​​
  • ​​3、传递方式​​
  • ​​二、选项与示例​​
  • ​​1、选项​​
  • ​​2、示例​​
  • ​​三、 正则表达式​​
  • ​​1、 正则表达式介绍​​
  • ​​2、 正则表达式元字符​​
  • ​​2.1、基本正则元字符集​​
  • ​​示例​​
  • ​​Ps: grep匹配换行符和制表符​​
  • ​​2.2 、扩展正则元字符集​​
  • ​​示例​​
  • ​​总结​​
  • ​​2.3 posix定义的字符分类​​
  • ​​四 、练习​​
  • ​​正则表达式及字符处理​​
  • ​​grep练习​​
  • ​​1、显示/proc/meminfo文件中以不区分大小的s开头的行​​
  • ​​2、显示/etc/passwd中以nologin结尾的行​​
  • ​​3、显示/etc/inittab中以#开头,且后面跟一个或多个空白字符,而后又跟了任意字符的行​​
  • ​​4、显示/etc/inittab中包含了:一个数字:(即两个冒号中间一个数字)的行​​
  • ​​5、显示/boot/grub/grub.conf文件中以一个或多个空白字符开头的行​​
  • ​​6、显示/etc/inittab文件中以一个数字开头并以一个与开头数字相同的数字结尾的行​​
  • ​​7、ip a命令可以显示当前主机的IP地址相关的信息等,要求不包括127.0.0.1​​
  • ​​8、显示/etc/sysconfig/network-scripts/ifcfg-eth0文件中的包含了类似IP地址点分十进制数字格式的行​​

三剑客之grep命令

一 、grep介绍

1、grep命令主要用于过滤文本,grep家族如下
grep: 在文件中全局查找指定的正则表达式,并打印所有包含该表达式的行
egrep:扩展的egrep,支持更多的正则表达式元字符 #egrep = grep -E
fgrep:固定grep(fixed grep),有时也被称作快速(fast grep),它按字面解释所有的字符      
2、grep命令格式如下
grep [选项] PATTERN 文件1 文件2 ...

[root@mm ~]# grep 'root' /etc/passwd
[root@mm ~]# fgrep 'bash' /etc/passwd

找到:       grep返回的退出状态为0
没找到:          grep返回的退出状态为1
找不到指定文件:      grep返回的退出状态为2
# 查看IP
[root@openvpn ~]# egrep -r '192.168.15.125' /etc/
/etc/sysconfig/network-scripts/ifcfg-eth0:IPADDR=192.168.15.125
/etc/openvpn/client/mm/mm.ovpn:remote 192.168.15.125 1194      
3、传递方式
grep 命令的输入可以来自标准输入或管道,而不仅仅是文件,例如:
ps aux |grep 'nginx'      

二、选项与示例

1、选项
-n, --line-number     在过滤出的每一行前面加上它在文件中的相对行号
-o, --only-matching     只显示匹配的内容
-q, --quiet, --silent   静默模式,没有任何输出,得用$?来判断执行成功没有,即有没有过滤到想要的内容
--color           颜色
-i, --ignore-case     忽略大小写
-A, --after-context=NUM   如果匹配成功,则将匹配行及其后n行一起打印出来
-B, --before-context=NUM  如果匹配成功,则将匹配行及其前n行一起打印出来
-C, --context=NUM     如果匹配成功,则将匹配行及其前后n行一起打印出来
-c, --count         如果匹配成功,则将匹配到的行数打印出来
-v, --invert-match      反向查找,只显示不匹配的行
-w              匹配单词
-E              等于egrep,扩展



-l, --files-with-matches  如果匹配成功,则只将文件名打印出来,失败则不打印
              通常-rl一起用,grep -rl 'root' /etc 
-r, --recursive         递归,链接文件不算
-R                           递归,链接文件也算      
2、示例
# 1、-n
[root@mm ~]# grep -n 'root' /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin
[root@mm ~]# 

# 2、-o
[root@mm ~]# grep -o 'root' /etc/passwd
root
root
root
root
[root@mm ~]# 

# 3、-q
[root@mm ~]# grep -q 'root' /etc/passwd 
[root@mm ~]# echo $?
0

# 4、--color
[root@mm ~]# alias grep
alias grep='grep --color=auto'
[root@mm ~]# 

# 5、-i
[root@mm ~]# echo "mm" |grep -i mm 
mm
[root@mm ~]# 

# 6、-A\-B\-C
[root@mm ~]# grep -A 2 'root' /etc/passwd
[root@mm ~]# grep -B 2 'root' /etc/passwd
[root@mm ~]# grep -C 2 'root' /etc/passwd

# 7、-c
[root@mm ~]# grep -c 'root' /etc/passwd
2
[root@mm ~]# 

# 8、-v
[root@mm ~]# ps aux | grep nginx |grep -v grep
[root@mm ~]# ps aux | grep [n]ginx
[root@mm ~]# 

# 9、-w   #三者相等
[root@mm ~]# netstat -an |grep -w 80
tcp6       0      0 :::80                   :::*                    LISTEN    
[root@mm ~]# netstat -an |grep  '\<80\>'
tcp6       0      0 :::80                   :::*                    LISTEN    
[root@mm ~]# netstat -an |grep  '\b80\b'
tcp6       0      0 :::80                   :::*                    LISTEN   
                                              
# 10、-rl
[root@mm ~]# grep -rl 'root' /etc  # 将/etc目录下所有包含'root'内容的文件都列出来

# 11、把/etc/下所有root过滤出来
[root@openvpn grep]# grep -Roi 'root' /etc/ |wc  -l
1552
[root@openvpn grep]# grep -roi 'root' /etc/ |wc  -l # r比较准确
891
# 12、把/etc/下所有root文件数过滤出来
[root@openvpn grep]# grep -riol 'root' /etc/ |wc -l
121      

三、 正则表达式

#grep -E ===  egrep
# 这两则都可以,推荐egrep正则      
1、 正则表达式介绍
**正则表达式**,又称规则表达式**。**(英语:Regular Expression,在代码中常简写为regex、regexp或RE),是计算机科学的一个概念。正则表达式由元字符组成,通常被用来检索、替换那些符合某个模式(规则)的文本(许多程序设计语言都支持利用正则表达式进行字符串操作)。      
shell元字符(也称为通配符): 由shell解释器来解析,如rm -rf *.pdf,元字符*Shell将其解析为任意多个字符
正则表达式元字符     : 由各种执行模式匹配操作的程序来解析,比如vi、grep、sed、awk

例如:vim示例:
:1,$ s/tom/mm/g    # 如anatomy、tomatoes及tomorrow中的“tom”被替换了,而Tom确没被替换
:1,$ s/\<[Tt]om\>/mm/g      

2、 正则表达式元字符

2.1、基本正则元字符集
元字符     功能                      示例  
^         行首                    ^love
$         行尾                     love$
.         除了换行符以外的任意单个字符           l..e
*         前导字符的零个或多个                ab*love
.*        所有字符                    a.*love
[]        字符组内的任一字符                [lL]ove
[^]       对字符组内的每个字符取反(不匹配字符组内的每个字符)   [^a-z0-9]ove
^[^]        非字符组内的字符开头的行

[a-z]       小写字母
[A-Z]       大写字母
[a-Z]         小写和大写字母
[0-9]         数字

\        用来转义元字符                    love\.  
\<          词首定位符 单词一般以空格或特殊字符做分隔、连续的字符组成  \<love
\>        词尾定位符                       love\>
\(..\)      匹配稍后将要使用的字符的标签                  \(love\)able\1er  
                                                         :1,$ s/\(192.168.11\).66/\1.50/g

x\{m\}      字符x重复出现m次                  e\{3\}
x\{m,\}     字符x重复出现m次以上               e\{3,\}           
x\{m,n\}    字符x重复出现m到n次               e\{3,6\}  

'\<1194\>' = w  # w和\<1194\>一样
[root@openvpn ~]# netstat  -lntp | grep '\b1194\b'
tcp        0      0 0.0.0.0:1194            0.0.0.0:*               LISTEN      7223/openvpn        
[root@openvpn ~]# netstat  -lntp | grep '\<1194\>'
tcp        0      0 0.0.0.0:1194            0.0.0.0:*               LISTEN      7223/openvpn        
[root@openvpn ~]# netstat  -lntp | grep '1194'
tcp        0      0 0.0.0.0:1194            0.0.0.0:*               LISTEN      7223/openvpn        
[root@openvpn ~]# netstat  -lntp | grep -w '1194'
tcp        0      0 0.0.0.0:1194            0.0.0.0:*               LISTEN      7223/openvpn          
示例
# 1、^ 行首
[root@mm ~]# grep '^root' /etc/passwd
root:x:0:0:root:/root:/bin/bash

# 2、$ 行尾
[root@openvpn grep]# grep 'bash$' /etc/passwd
root:x:0:0:root:/root:/bin/bash
www:x:666:666::/home/www:/bin/bash 

# 3、. 除了换行符以外的任意单个字符
[root@openvpn grep]# grep 'r..t' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

# 4、* 前导字符的零个或多个
[root@mm ~]# cat a.txt 
a
ab
abb
abbb
bbbbb
[root@mm ~]# grep 'ab*' a.txt 
a
ab
abb
abbb

# 5、.* 所有字符=贪婪
[root@mm ~]# cat a.txt 
a123+-*/c11113333c
a1c
a77Ac
a23333c
ac
111
222
333
[root@mm ~]# grep 'a.*c' a.txt 
a123+-*/c11113333c
a1c
a77Ac
a23333c
ac

# 5.1 .*?=》非贪婪,默认情况下,grep不支持非贪婪修饰符,但您可以使用grep -P来使用Perl语法来支持.*?
[root@openvpn grep]# cat ping.sh 
<a  href="https://www.jd.vom">"我是京东"</a>
<a  href="https://www.taobao.vom">"我是淘宝"</a>

[root@openvpn grep]# grep 'href=".*"' ping.sh  #贪婪
<a  href="https://www.jd.vom">"我是京东"</a>
<a  href="https://www.taobao.vom">"我是淘宝"</a>

[root@openvpn grep]# grep -P 'href=".*?"' ping.sh  #非贪婪
<a  href="https://www.jd.vom">"我是京东"</a>
<a  href="https://www.taobao.vom">"我是淘宝"</a>


[root@openvpn grep]# grep -oP 'href=".*?"' ping.sh # 正则 
href="https://www.jd.vom"
href="https://www.taobao.vom" 

# 6、[] 字符组内的任一字符

# 7、[^] 对字符组内的每个字符取反(不匹配字符组内的每个字符)
[root@mm ~]# cat a.txt 
a1c
a2c
a33c
aAc
aZc
[root@mm ~]# grep 'a[0-9]c' a.txt
a1c
a2c
[root@mm ~]# grep 'a[^0-9]c' a.txt
aAc
aZc
[root@mm ~]# 
[root@mm ~]# grep 'a[0-9][0-9]c' a.txt
a33c
[root@mm ~]# 

# 8、^[^] 非字符组内的字符开头的行
[root@openvpn grep]# cat a.tt
a1b
as2b
a9b
asb
ba
aad
dad
[root@openvpn grep]# egrep '^[^#\ ]' /etc/ansible/ansible.cfg  以#号开头的行 #\后面是空格
[defaults]
command_warnings=False
host_key_checking = False
log_path = /var/log/ansible.log
[inventory]
[privilege_escalation]
[paramiko_connection]
[ssh_connection]
[persistent_connection]
[accelerate]
[selinux]
[colors]
[diff]
[root@openvpn grep]# grep '^[ab]' a.tt #以a或者b开头的
a1b
as2b
a9b
asb
ba
aad
dad
[root@openvpn grep]# grep '^[^ab]' a.tt # 不以a或b开头的
dad

# 9、[a-z] 小写字母
# 10、[A-Z] 大写字母
# 11、[a-Z] 小写和大写字母
# 12、[0-9] 数字
# 正则
[root@openvpn grep]# cat a.tt
a1b
asb
a+b
a-zb
a2
as2b
a9b
asb
[root@openvpn grep]# grep 'a[-+*/]b' a.tt #减号在前或者在后
a+b
[root@openvpn grep]# grep 'a[^-+*/]b' a.tt #不包含里面的加减乘除符合
a1b
asb
a9b
asb

[root@openvpn grep]# cat a.tt
a1b
asb
a+b
a-zb
a2
as2b
a9b
asb

[root@openvpn grep]# grep 'a[0-9]b' a.tt
a1b
a9b

# 13、\< 单词头 单词一般以空格或特殊字符做分隔,连续的字符串被当做单词
# 14、\> 单词尾
[root@mm ~]# netstat -an |grep -w 80
tcp6       0      0 :::80                   :::*                    LISTEN    
[root@mm ~]# netstat -an |grep  '\<80\>'
tcp6       0      0 :::80                   :::*                    LISTEN    
[root@mm ~]# netstat -an |grep  '\b80\b'
tcp6       0      0 :::80                   :::*                    LISTEN         
Ps: grep匹配换行符和制表符
[root@mm ~]# echo -e "a\nb" |grep $'a\nb'
a
b
[root@mm ~]# 
[root@mm ~]# echo -e "a\tb" |grep $'a\tb'
a b
[root@mm ~]#       
2.2 、扩展正则元字符集
# 扩展正则元字符
+         匹配一个或多个前导字符      [a-z]+ove  
?         匹配零个或一个前导字符      lo?ve  
a|b         匹配a或b            love|hate
()          组字符            love(able|rs)  (mm)+
(..)(..)\1\2    标签匹配字符           (love)able\1er
x{n}          x出现n次              e{3}   
x{n,}         x出现n次至无穷次        e{3,}
x{n,m}            x出现n次至m次             e{3,6}

# 若想使用扩展正则
grep加-E 或 egrep 或转义\

[root@openvpn grep]# cat 1.txt 
222kkmkkm4354
323454
123mm34
2334mmm32435456
mm11
3245354mm
34mmmm3456
[root@openvpn grep]# egrep 'kkmkkm' 1.txt 
222kkmkkm4354


sed 加 -r 参数 或转义

AWK 直接支持大多数扩展正则,更多支持需要加选项--posix选项

[root@openvpn grep]# egrep -v '^$|^#' /etc/ansible/ansible.cfg  
#^$ = 等于空格
[defaults]
command_warnings=False
host_key_checking = False
log_path = /var/log/ansible.log
[inventory]
[privilege_escalation]
[paramiko_connection]
[ssh_connection]
[persistent_connection]
[accelerate]
[selinux]
[colors]
[diff]      
示例
# ======================grep扩展正则示例======================
[root@mm ~]# cat a.txt 
a

ab
abb
abbb
abbbb
abbbbb
bbbbbbb
[root@mm ~]# grep 'ab{2,4}' a.txt  # 默认不支持扩展正则,所以没效果
[root@mm ~]# egrep 'ab{2,4}' a.txt 
abb
abbb
abbbb
abbbbb
[root@mm ~]# 

# ======================sed扩展正则示例======================
[root@mm ~]# sed -n '/roo?/p' /etc/passwd  # 默认不支持扩展正则?
[root@mm ~]# sed -n '/roo\?/p' /etc/passwd  # 可以用\转义扩展正则符号?
有结果,结果略...
[root@mm ~]# sed -rn '/roo?/p' /etc/passwd  # 也可以加-r选项
有结果,结果略...
[root@mm ~]# 

# ======================awk扩展正则示例======================
[root@mm ~]# cat a.txt 
a

ab
abb
abbb
abbbb
abbbbb
bbbbbbb
[root@mm ~]# awk '/ab{1,3}/{print}' a.txt
ab
abb
abbb
abbbb
abbbbb
[root@mm ~]# awk --posix '/ab{1,3}/{print}' a.txt
ab
abb
abbb
abbbb
abbbbb      
总结
grep:       使用基本元字符集  ^, $, ., *, [], [^], \< \>,\(\),\{\}
egrep(或grep -E):  使用扩展元字符集  ?, +, { }, |, ( )
# 注:grep也可以使用扩展集中的元字符,仅需要对这些元字符前置一个反斜线

\w  所有字母与数字,称为字符[a-zA-Z0-9]    'l[a-zA-Z0-9]*ve'        'l\w*ve'
\W  所有字母与数字之外的字符,称为非字符     'love[^a-zA-Z0-9]+'          'love\W+'
\b  词边界               '\blove\b'            '\<love\>'      
2.3 posix定义的字符分类
# 表达式           功能                                    示例
[:alnum:]       字母与数字字符                           [[:alnum:]]+  
[:alpha:]       字母字符(包括大小写字母)           [[:alpha:]]{4}
[:blank:]       空格与制表符                              [[:blank:]]*
[:digit:]       数字字母                              [[:digit:]]?
[:lower:]       小写字母                                [[:lower:]]{5,}
[:upper:]       大写字母                                [[:upper:]]+
[:punct:]       标点符号                                [[:punct:]]
[:space:]       包括换行符,回车等在内的所有空白[[:space:]]+


# 详解
[:alnum:] Alphanumeric characters.
匹配范围为 [a-zA-Z0-9]
[:alpha:] Alphabetic characters.
匹配范围为 [a-zA-Z]
[:blank:] Space or tab characters.
匹配范围为 空格和TAB键
[:cntrl:] Control characters.
匹配控制键 例如 ^M 要按 ctrl+v 再按回车 才能输出
[:digit:] Numeric characters.
匹配所有数字 [0-9]
[:graph:] Characters that are both printable and visible. (A space is print-
able, but not visible, while an a is both.)
匹配所有可见字符 但不包含空格和TAB 就是你在文本文档中按键盘上能用眼睛观察到的所有符号
[:lower:] Lower-case alphabetic characters.
小写 [a-z]
[:print:] Printable characters (characters that are not control characters.)
匹配所有可见字符 包括空格和TAB
能打印到纸上的所有符号
[:punct:] Punctuation characters (characters that are not letter, digits, con-
trol characters, or space characters).
特殊输入符号 +-=)(*&^%$#@!~`|\"'{}[]:;?/>.<,
注意它不包含空格和TAB
这个集合不等于^[a-zA-Z0-9]
[:space:] Space characters (such as space, tab, and formfeed, to name a few).

[:upper:] Upper-case alphabetic characters.
大写 [A-Z]
[:xdigit:] Characters that are hexadecimal digits.
16进制数 [0-f]

# 使用方法:
[root@mm ~]# grep --color '[[:alnum:]]' /etc/passwd      

四 、练习

正则表达式及字符处理
目标文件/etc/passwd,使用grep命令或egrep
1.显示出所有含有root的行:
[root@openvpn grep]# grep 'root' passwd.txt  |wc -l
2
2.输出任何包含bash的所有行,还要输出紧接着这行的上下各两行的内容:
[root@openvpn grep]# egrep  -C 2 'bash' /etc/passw
3.  显示出有多少行含有nologin。
[root@openvpn grep]# grep  'nologin' /etc/passwd |wc -l
24
4.显示出那些行含有root,并将行号一块输出。
[root@openvpn grep]# grep  -n 'root' /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin
5.显示出文件中
[root@openvpn grep]# grep  -n 'root' /etc/passwd > passwd.txt 
[root@openvpn grep]# cat passwd.txt 
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin
6.新建用户
    abominable
    abominate
    anomie
    atomize
    编写正则表达式,将他们匹配出来
[root@openvpn grep]# egrep 'a.omi(nabl|nat|z|)e' /etc/passwd
7.建四个用户
    Alex213sb
    Wpq2222b
    yH438PIG
    mm666
    mm

    过滤出用户名组成是字母+数字+字母的行
[root@openvpn grep]# egrep '^[a-Z]+[0-9]+[a-Z]+' /etc/passwd
8.显示出/etc目录下所有包含root的文件名
[root@openvpn grep]# egrep -rl 'root' /etc/
9. 过滤掉/etc/ssh/sshd_config内所有注释和所有空行
[root@openvpn grep]# egrep -v '^#|^$'  /etc/ssh/sshd_config
[root@openvpn sed]# egrep  '^[^#]' /etc/ssh/sshd_config      
grep练习
1、显示/proc/meminfo文件中以不区分大小的s开头的行
[root@m01 ~]# grep -i '^s' /proc/meminfo
SwapCached:            0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Shmem:              7792 kB
Slab:              57176 kB
SReclaimable:      28856 kB
SUnreclaim:        28320 kB      
2、显示/etc/passwd中以nologin结尾的行
[root@m01 ~]# grep -E 'nologin$' /etc/passwd      
3、显示/etc/inittab中以#开头,且后面跟一个或多个空白字符,而后又跟了任意字符的行
[root@openvpn grep]# egrep '^#\ +.*' /etc/inittab 
# inittab is no longer used when using systemd.
# ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
# Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target
# systemd uses 'targets' instead of runlevels. By default, there are two main targets:
# multi-user.target: analogous to runlevel 3
# graphical.target: analogous to runlevel 5
# To view current default target, run:
# systemctl get-default
# To set a default target, run:
# systemctl set-default TARGET.target      
4、显示/etc/inittab中包含了:一个数字:(即两个冒号中间一个数字)的行
[root@openvpn grep]# egrep ':[0-9]:' /etc/inittab       
5、显示/boot/grub/grub.conf文件中以一个或多个空白字符开头的行
[root@openvpn grep]# egrep  '^\ +' /boot/grub/grub.con      
6、显示/etc/inittab文件中以一个数字开头并以一个与开头数字相同的数字结尾的行
[root@openvpn grep]# cat 1.txt 
222kkmkkm4354
2334mmm32435452
mm11
3245354mm
34mmmm3456
[root@openvpn grep]# egrep '(^[0-9]{1}).*\1$'  1.txt 
2334mmm32435452      
7、ip a命令可以显示当前主机的IP地址相关的信息等,要求不包括127.0.0.1
[root@openvpn grep]#  ip a | grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v "127"      
8、显示/etc/sysconfig/network-scripts/ifcfg-eth0文件中的包含了类似IP地址点分十进制数字格式的行
[root@openvpn grep]# egrep -o '([0-9]{1,3}\.){3}[0-9]{1,3}' /etc/sysconfig/network-scripts/ifcfg-eth0
192.168.15.125
192.168.15.2
223.5.5.5