‘Linux系统中的grep命令是一种功能强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所有用户。
语法参数
Grep常用参数详解如下:
-a 以文本文件方式搜索(默认参数)
-c 计算找到的符合行的次数
-i 忽略大小写
-n 顺便输出行号
-v 反向选择,即显示不包含匹配文本的所有行
-h 查询多文件时不显示文件名
-l 查询多文件时只输出包含匹配字符的文件名
-r 相当于--directories=recurse 遍历目录
-s 不显示不存在或无匹配文本的错误信息
-E 允许使用egrep扩展模式匹配
-o 表示“only-matching”,即“仅匹配”之意(获取匹配到的字符串)
grep 命令格式
grep [选项] PATTERN filename filename ...
- 在每个 FILE 或是标准输入中查找 PATTERN。默认的 PATTERN 是一个基本正则表达式(缩写为 BRE)。
[root@bogon ~]# grep -i 'hello world' menu.h main.c
实例 1:查找指定进程个数
[root@bogon ~]# ps -ef | grep http -c
7
[root@bogon ~]# ps -ef | grep -c http
7
[root@bogon ~]# grep 'linux' test1.txt
hnlinux
ubuntu linux
linux
[root@bogon ~]# grep -n 'linux' test1.txt
1:hnlinux
3:ubuntu linux
6:linux
实例 3:从多个文件中查找关键词
[root@bogon ~]# grep 'linux' test1.txt test2.txt
test1.txt:hnlinux
test1.txt:ubuntu linux
test1.txt:linux
test2.txt:linux
[root@bogon ~]# ps aux|grep ssh|grep -v 'grep'
root 1036 0.0 0.4 112924 4312 ? Ss 06:50 0:00
/usr/sbin/sshd -D
root 2491 0.0 0.5 156784 5560 ? Ss 06:52 0:00
sshd: root@pts/0
实例 5:找出已 u 开头的行内容
[root@bogon ~]# cat test1.txt | grep ^u
ubuntu
ubuntu linux
[root@bogon ~]# cat test1.txt | grep -v ^u
hnlinux
redhat
Redhat
linux
centos
[root@bogon ~]# cat test1.txt | grep hat$
redhat
Redhat
[root@bogon ~]#ifconfig ens33|grep
"[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}\.[0-9]\{1,3\}"
inet 192.168.43.101
netmask 255.255.255.0
broadcast 192.168.43.255
[root@bogon ~]# ifconfig ens33|grep -E "([0-9]{1,3}\.){3}[0-9]"
inet 192.168.43.101
netmask 255.255.255.0
broadcast
192.168.43.255
[root@bogon ~]# grep '[a-z]\{7\}' *.txt
test1.txt:hnlinux
grep -v
过滤不带有某个关键词的行,并输出行号
[root@localhost ~]# grep -nv 'nologin' /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
6:sync:x:5:0:sync:/sbin:/bin/sync
7:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8:halt:x:7:0:halt:/sbin:/sbin/halt
26:test:x:511:511::/home/test:/bin/bash
27:test1:x:512:511::/home/test1:/bin/bash
过滤出所有包含数字的行
[root@localhost ~]# grep '[0-9]' /etc/inittab
# upstart works, see init(5), init(8), and initctl(8).
# 0 - halt (Do NOT set initdefault to this)
# 1 - Single user mode
# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)
# 3 - Full multiuser mode
# 4 - unused
# 5 - X11
# 6 - reboot (Do NOT set initdefault to this)
id:3:initdefault:
过滤出所有不包含数字的行
[root@localhost ~]# grep -v '[0-9]' /etc/inittab
# inittab is only used by upstart for the default runlevel.
#
# ADDING OTHER CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
#
# System initialization is started by /etc/init/rcS.conf
#
# Individual runlevels are started by /etc/init/rc.conf
#
# Ctrl-Alt-Delete is handled by /etc/init/control-alt-delete.conf
#
# Terminal gettys are handled by /etc/init/tty.conf and /etc/init/serial.conf,
# with configuration in /etc/sysconfig/init.
#
# For information on how to write upstart event handlers, or how
#
# Default runlevel. The runlevels used are:
#
把所有以 ‘#' 开头的行去除
[root@localhost ~]# grep -v '^#' /etc/inittab
id:3:initdefault:
去除所有空行和以 ‘#' 开头的行
[root@localhost ~]# grep -v '^#' /etc/crontab |grep -v '^$'
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
在正则表达式中, “^” 表示行的开始, “$” 表示行的结尾,那么空行则可以用 “^$” 表示,如何打印出不以英文字母开头的行呢?
[root@localhost ~]# vim test.txt
[root@localhost ~]# cat test.txt
123
abc
456
abc2323
#laksdjf
Alllllllll
先在test.txt中写几行字符串,用来做实验。
[root@localhost ~]# grep '^[^a-zA-Z]' test.txt
123
456
#laksdjf
[root@localhost ~]# grep '[^a-zA-Z]' test.txt
123
456
abc2323
#laksdjf
如果是数字的话就用[0-9]这样的形式,当然有时候也可以用这样的形式[15]即只含有1或者5,注意,它不会认为是15。如果要过滤出数字以及大小写字母则要这样写[0-9a-zA-Z]。另外[ ]还有一种形式,就是[^字符] 表示除[ ]内的字符之外的字符。
实战使用grep过滤关键字
使用grep在单个文件检索
[root@www ~]# cat score.txt
Aaron Physics 87
Abel Maths 98
Rahul Chinese 90
Buck Biology 87
Byron English 85
Dave History 89
Enoch Chemistry 89
#查找包含“87”的行
[root@www ~]# grep 87 score.txt
Aaron Physics 87
Buck Biology 87
#查找不包含87的行并且打印行号
[root@www ~]# grep -vn 87 score.txt
2:Abel Maths 98
3:Rahul Chinese 90
5:Byron English 85
6:Dave History 89
7:Enoch Chemistry 89
# -n选项打印行号
[root@localhost ~]# grep -n '87' score.txt
1:Aaron Physics 87
4:Buck Biology 87
[root@localhost ~]# grep -n '87' score.txt | awk -F'[: ]' '{print $1,$NF}'
1 87
4 87
#把所有的内容都打印出来
[root@www ~]# grep -n '' score.txt
1:Aaron Physics 87
2:Abel Maths 98
3:Rahul Chinese 90
4:Buck Biology 87
5:Byron English 85
6:Dave History 89
7:Enoch Chemistry 89
# -o选项 不会将行打印出来,只打印匹配到的
[root@www ~]# grep -o Buck score.txt
Buck
#统计文本里面匹配到不区分大小写abel,然后统计次数出现多少次
[root@www ~]# grep -aci 'abel' score.txt
1
#忽略大小写i v不匹配
[root@localhost ~]# grep -avi rahul score.txt
Aaron Physics 87
Abel Maths 98
Buck Biology 87
Byron English 85
Dave History 89
Enoch Chemistry 89
#grep可用于shell脚本,因为grep通过返回一个状态值来说明搜索的状态,如果模板搜索成功,则返回0,如果搜索不成功,则返回1,如果搜索的文件不存在,则返回2。我们利用这些返回值就可进行一些自动化的文本处理工作。
[root@www ~]# grep "static" /etc/sysconfig/network-scripts/ifcfg-ens33
BOOTPROTO="static"
[root@www ~]# echo $?
0
[root@www ~]# grep "dhcp" /etc/sysconfig/network-scripts/ifcfg-ens33
[root@www ~]# echo $?
1
通过grep和if实现某些判断条件
[root@www ~]# num=$(grep static /etc/sysconfig/network-scripts/ifcfg-ens33|wc -l)
[root@www ~]# echo $num
1
grep在同一目录下多文件关键字的检索
[root@localhost ~]# cp score.txt score.txt1
[root@localhost ~]# cp score.txt score.txt2
#可以从多个文件检索
[root@localhost ~]# grep -i aaron score.txt score.txt1 score.txt2
score.txt:Aaron Physics 87
score.txt1:Aaron Physics 87
score.txt2:Aaron Physics 87
或者
[root@localhost ~]# grep -i aaron score.txt*
score.txt:Aaron Physics 87
score.txt1:Aaron Physics 87
score.txt2:Aaron Physics 87
#查询多个文件不显示文件名
[root@localhost ~]# grep -ih aaron score.txt*
Aaron Physics 87
Aaron Physics 87
Aaron Physics 87
#只看文件名,查询到文件名可以使用for循环然后使用sed替换Aaron的值
[root@localhost ~]# grep -l 'Aaron' score.txt*
score.txt
score.txt1
score.txt2
[root@localhost ~]# for i in `grep -l 'Aaron' score.txt*`;do echo $i;done
score.txt
score.txt1
score.txt2
[root@localhost ~]# for i in `grep -l 'Aaron' score.txt*`;do sed s/Aaron/replace/g $i;done
replace Physics 87
Abel Maths 98
Rahul Chinese 90
Buck Biology 87
Byron English 85
Dave History 89
Enoch Chemistry 89
replace Physics 87
Abel Maths 98
Rahul Chinese 90
Buck Biology 87
Byron English 85
Dave History 89
Enoch Chemistry 89
replace Physics 87
Abel Maths 98
Rahul Chinese 90
Buck Biology 87
Byron English 85
Dave History 89
Enoch Chemistry 89
#查看关键字出现次数
[root@www ~]# grep -aci aaron socre.txt socre1.txt socre2.txt
socre.txt:1
socre1.txt:1
socre2.txt:1
grep在多级目录下多文件关键字的检索(使用-r)
[root@localhost ~]# grep -i aaron *
grep: a: Is a directory
grep: b: Is a directory
grep: c: Is a directory
score1.txt:Aaron Physics 87
score2.txt:Aaron Physics 87
score.txt:Aaron Physics 87
可以看到如果目录分级了就过滤不了关键字aaron需要使用-r
[root@localhost ~]# grep -ir aaron *
a/score.txt:Aaron Physics 87
b/score.txt:Aaron Physics 87
c/score.txt:Aaron Physics 87
score1.txt:Aaron Physics 87
score2.txt:Aaron Physics 87
score.txt:Aaron Physics 87
[root@localhost ~]# grep -irl aaron *
a/score.txt
b/score.txt
c/score.txt
score1.txt
score2.txt
score.txt
批量替换将aaron替换为test
[root@localhost ~]# for i in `grep -irl aaron *`;do sed -n 's/Aaron/test/p' $i;done
test Physics 87
test Physics 87
test Physics 87
test Physics 87
test Physics 87
test Physics 87