Linux (三剑客之一) grep字符串搜索命令详解

(1)grep命令简介

    Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来。grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所有用户。
    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的功能。


(2)grep命令格式
grep能够快速的对文件进行搜索,命令和参数都比较好理解:

grep [-acinv] [--color=auto] '搜寻字符串' filename1 filename2 可以在多个文件中搜索
选项与参数:

-a :将 binary 文件以 text 文件的方式搜寻数据
-c :计算找到 '搜寻字符串' 的次数
-i :忽略大小写的不同,所以大小写视为相同
-n :顺便输出行号
-v :反向选择,亦即显示出没有 '搜寻字符串' 内容的那一行!

--color=auto :可以将找到的关键词部分加上颜色的显示喔!


1.例:输出带行号,-n输出行号,-c统计搜索到的行数
[root@network1 ~]# grep  -n sed linux-auto-init.sh  
24:sed -i 's/ONBOOT=no/ONBOOT=yes/' /etc/sysconfig/network-scripts/ifcfg-em2 
25:sed -i 's/BOOTPROTO=dhcp/BOOTPROTO=static/' /etc/sysconfig/network-scripts/ifcfg-em2 
26:sed -i '/NETBOOT=yes/d' /etc/sysconfig/network-scripts/ifcfg-em2 

2.例:在多个文件中搜索,-v表示反向搜索

[root@computer1 ~]# grep -v "#" linux-auto-init.sh test.sh 
linux-auto-init.sh:
linux-auto-init.sh:init_name="network1"
linux-auto-init.sh:init_ip="172.16.70.71"
linux-auto-init.sh:hostnamectl set-hostname ${init_name}

详细选项:

-a 不要忽略二进制数据。
-A<显示列数> 除了显示符合范本样式的那一行之外,并显示该行之后的内容。
-b 在显示符合范本样式的那一行之外,并显示该行之前的内容。
-c 计算符合范本样式的列数。
-C<显示列数>或-<显示列数>  除了显示符合范本样式的那一列之外,并显示该列之前后的内容。
-d<进行动作> 当指定要查找的是目录而非文件时,必须使用这项参数,否则grep命令将回报信息并停止动作。
-e<范本样式> 指定字符串作为查找文件内容的范本样式。
-E 将范本样式为延伸的普通表示法来使用,意味着使用能使用扩展正则表达式。
-f<范本文件> 指定范本文件,其内容有一个或多个范本样式,让grep查找符合范本条件的文件内容,格式为每一列的范本样式。
-F 将范本样式视为固定字符串的列表。
-G 将范本样式视为普通的表示法来使用。
-h 在显示符合范本样式的那一列之前,不标示该列所属的文件名称。
-H 在显示符合范本样式的那一列之前,标示该列的文件名称。
-i 胡列字符大小写的差别。
-l 列出文件内容符合指定的范本样式的文件名称。
-L 列出文件内容不符合指定的范本样式的文件名称。
-n 在显示符合范本样式的那一列之前,标示出该列的编号。
-q 不显示任何信息。
-R/-r 此参数的效果和指定“-d recurse”参数相同。
-s 不显示错误信息。
-v 反转查找。
-w 只显示全字符合的列。
-x 只显示全列符合的列。
-y 此参数效果跟“-i”相同。
-o 只输出文件中匹配到的部分。

3.多个搜索条件-e,条件之间是或的关系
[root@computer1 ~]# grep -e '^[a-c]' -e "^sys" linux-auto-init.sh 
cat >/etc/sysconfig/network-scripts/ifcfg-em2 << END
systemctl restart network
cat >/etc/hosts << EOF
systemctl disable firewalld
systemctl stop firewalld

4.递归搜索 -r,搜索/etc/所有子目录下以sys开头的行
[root@computer1 /]# grep -r '^sys' /etc/
/etc/services:syslog-tls      6514/udp                # Syslog over TLS
/etc/services:syslog-tls      6514/dccp               # Syslog over TLS
/etc/services:sysinfo-sp      11967/tcp               # SysInfo Service Protocol
/etc/services:sysinfo-sp      11967/udp               # SysInfo Sercice Protocol
/etc/shadow:systemd-network:!!:17655::::::
/etc/rc.d/init.d/README:systemctl(1).
/etc/rc.d/init.d/README:system. An init script /etc/rc.d/init.d/foobar is implicitly mapped
/etc/rc.d/init.d/functions:systemctl_redirect () {
/etc/passwd-:systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin

#在目录下,指定在xxx.xxx文件中搜索
grep  "ERROR"  /var/ -r --include "*.log"

#在搜索结果中排除所有xxx.xxx文件
grep "xxx" . -r --exclude "xxx.xxx"

[root@computer1 /]# grep  "ERROR"  /var/ -r --exclude "*.xml"
Binary file /var/lib/rpm/Packages matches
Binary file /var/lib/rpm/Basenames matches
Binary file /var/lib/rpm/__db.003 matches
Binary file /var/lib/mlocate/mlocate.db matches
/var/log/tuned/tuned.log:2018-05-04 10:04:20,644 ERROR    tuned.utils.commands: Executing x86_energy_perf_policy error: 
/var/log/tuned/tuned.log:2018-05-04 10:04:20,667 ERROR    tuned.utils.commands: Error when reading file '/sys/class/drm/card0/device/power_method': '[Errno 2] No such file or directory: u'/sys/class/drm/card0/device/power_method''
/var/log/tuned/tuned.log:2018-05-04 10:25:46,834 ERROR    tuned.utils.commands: Executing 

#在搜索结果中排除filelist文件列表里的文件
grep "xxx" . -r --exclude-from filelist

(3)作为命令的管道进行搜索
在linux的命令中,有些命令显示了大量的内容,不容易查看可以通过grep过滤,得到想要的结果,如命令ps ax 显示了大量的,使用grep过滤相关进程。

[root@controller1 ~]# ps aux | grep httpd
root        927  0.0  0.3 230228  5712 ?      Ss   May29   0:37 /usr/sbin/httpd -DFOREGROUND
apache    15129  0.0  0.3 232384  7096 ?        S    Jun04   0:04 /usr/sbin/httpd -DFOREGROUND
apache    15130  0.0  0.3 232384  7092 ?        S    Jun04   0:04 /usr/sbin/httpd -DFOREGROUND
apache    15131  0.0  0.3 232384  7092 ?        S    Jun04   0:03 /usr/sbin/httpd -DFOREGROUND


1.例:利用|,进行多层过滤
grep pattern1 files | grep pattern2 #注意格式,文件名跟在第一个grep后面
[root@computer1 ~]# grep ^[0-9] linux-auto-init.sh
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
172.16.100.70 controller1 
172.16.100.71 network1
172.16.100.72 compute1
172.16.100.73 compute2
172.16.100.74 compute3
172.16.100.90 block

[root@computer1 ~]# grep ^[0-9] linux-auto-init.sh |grep '70'
172.16.100.70 controller1 

[root@computer1 ~]# 

2.例:表达式里面出现?+(){}| 特殊符号,需要用\转义
如果不转义,grep会出错,或者使用egrep或grep -E,此处对|进行转义,和例3中的egrep结果一样
[root@computer1 ~]# grep "^s\|^[0-9]" linux-auto-init.sh 
sed -i 's/ONBOOT=no/ONBOOT=yes/' /etc/sysconfig/network-scripts/ifcfg-em2 
sed -i 's/BOOTPROTO=dhcp/BOOTPROTO=static/' /etc/sysconfig/network-scripts/ifcfg-em2 
sed -i '/NETBOOT=yes/d' /etc/sysconfig/network-scripts/ifcfg-em2 
systemctl restart network
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
172.16.100.70 controller1 
172.16.100.71 network1
172.16.100.72 compute1
systemctl disable firewalld
systemctl stop firewalld

3.例:egrep扩展过滤,'^[s]|^[0-9]'表示以s头数字开头的行
[root@computer1 ~]# egrep '^[s]|^[0-9]' linux-auto-init.sh 
sed -i 's/ONBOOT=no/ONBOOT=yes/' /etc/sysconfig/network-scripts/ifcfg-em2 
sed -i 's/BOOTPROTO=dhcp/BOOTPROTO=static/' /etc/sysconfig/network-scripts/ifcfg-em2 
sed -i '/NETBOOT=yes/d' /etc/sysconfig/network-scripts/ifcfg-em2 
systemctl restart network
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
172.16.100.70 controller1 
172.16.100.71 network1
172.16.100.72 compute1
systemctl disable firewalld

systemctl stop firewalld


4.例:grep表达式中|表示或的意思
如果要表达条件与,只能用grep pattern1 files | grep pattern2
[root@computer1 ~]# grep "IPADDR\|GATEWAY"  /etc/sysconfig/network-scripts/ifcfg-em2
IPADDR=172.16.70.72
GATEWAY=172.16.70.10

5.例:()内表示一组,(oo)表示两oo一组,需要\转义(){}
[root@computer1 ~]# grep "\(oo\)\{2,5\}g" test.sh  
goooooooooooooooogl
wooooogl

(4)grep正则表达式

grep的正则跟其他语言的正则表达式有一些不同,认识到grep里的规则,就能容易写出grep的过滤条件。
RE(正则表达式)

^ 匹配正则表达式的开始行
$ 匹配正则表达式的结束行
< 从匹配正则表达式的行开始
> 到匹配正则表达式的行结束
[ ] 单个字符;如[A] 即A符合要求
[ - ] 范围 ;如[A-Z]即A,B,C一直到Z都符合要求

^[0-9] 以数字开始的行,[]内可列举字母
^[124ab] 以1,2,4,a,或b开头的行
^b.503 句点表示任一字母
* 星号表示0个以上的字母(可以没有)
+ 加号表示1个以上的字母
. 表示一个任意字符

\反斜线,转义符号,可以去掉特殊意义

1.例:[]表示范围
比如[a-z] 表示小写字母,[0-9] 表示0~9的数字, [A-Z] 则是大写字母们。[a-zA-Z0-9]表示所有数字与英文字符。 
[root@controller1 ~]# grep -n '^[a-Z]' admin-openrc 
2:export OS_PROJECT_DOMAIN_NAME=Default
3:export OS_USER_DOMAIN_NAME=Default
4:export OS_PROJECT_NAME=admin
5:export OS_USERNAME=admin
6:export OS_PASSWORD=ADMIN_PASS
7:export OS_AUTH_URL=http://172.16.70.201:5000/v3
8:export OS_IDENTITY_API_VERSION=3

2.例:[]里面的^和外面的^不同
[]里面的^ :表示反,外面的^:表示从行首开始
[root@computer1 ~]# grep -n '^[^a-zA-Z]' linux-auto-init.sh 
1:#!/bin/bash
23:#2.自动配置第二块网卡信息
51:#3.重启网络服务
54:     systemctl restart network
56:    site="www.qq.com"  
57:    ping -c1 -W1  ${site} &> /dev/null  
68:#4.更改/etc/hosts文件
70:127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
71:::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
72:172.16.100.70 controller1 
73:172.16.100.71 network1
74:172.16.100.72 compute1

3.例:'^$' 表示行首和行尾,即空行
搜索空行
[root@computer1 ~]# grep -n '^$' linux-auto-init.sh 
8:
19:
22:

4.例:转义符\ ,比如 '\.'
[root@computer1 ~]# grep -n '^[A-Z]' linux-auto-init.sh |grep '\.'   
45:NETMASK=255.255.255.0
46:GATEWAY=172.16.70.10
47:DNS1=202.96.128.166

48:DNS2=8.8.8.8

注意:此处grep -n '^[A-Z]' linux-auto-init.sh |grep '\.' (正确)和grep -n '^[A-Z]'|grep '\.' linux-auto-init.sh(错误)的区别。文件名,一定要跟在第一个grep 后面

5.例:[]中的^ - 不表现特殊意义,直接放在[]里面内容的后面。
表示没有字母,没有#没有空格,没有:没有!的串,注意[]里面有个小空格。
[root@computer1 ~]# grep -n '^[^a-Z^# :!]' linux-auto-init.sh 
54:     systemctl restart network
70:127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
72:172.16.100.70 controller1 
73:172.16.100.71 network1
74:172.16.100.72 compute1
75:172.16.100.73 compute2
76:172.16.100.74 compute3
另外shell 里面的反向选择为[!range], 正则里面是 [^range]

6.例:.号,找出p??l 的字串,亦即共有四个字节,起头是p而结束是l
[root@computer1 ~]# grep -n 'p..l' linux-auto-init.sh    
100:#server 0.centos.pool.ntp.org iburst
101:#server 1.centos.pool.ntp.org iburst
102:#server 2.centos.pool.ntp.org iburst
103:#server 3.centos.pool.ntp.org iburst

7.例:范围 { } 限定连续重复字符
. * 只能限制0个或多个, 如果要确切的限制字符重复数量,就用{范围} 。范围是数字用,隔开 2,5 表示2~5个,
2表示2个,2, 表示2到更多个,注意,由于{ }在SHELL中有特殊意义,因此作为正则表达式用的时候要用\转义一下。

#找到两个连续o的字串
[root@computer1 ~]# grep -n 'o\{2\}' linux-auto-init.sh 
100:#server 0.centos.pool.ntp.org iburst
101:#server 1.centos.pool.ntp.org iburst
102:#server 2.centos.pool.ntp.org iburst

#找出1到2个o,后再接一个l的字串
[root@computer1 ~]# grep -n 'o\{1,2\}l' linux-auto-init.sh 
72:172.16.100.70 controller1 
100:#server 0.centos.pool.ntp.org iburst
101:#server 1.centos.pool.ntp.org iburst
102:#server 2.centos.pool.ntp.org iburst
103:#server 3.centos.pool.ntp.org iburst
107:#其他节点如下修改,采用controller的时钟







  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值