Shell grep(2)

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

语法参数


Grep常用参数详解如下:

-a  以文本文件方式搜索(默认参数)

-c  计算找到的符合行的次数

-i   忽略大小写

-n  顺便输出行号

-v 反向选择,即显示不包含匹配文本的所有行

-h 查询多文件时不显示文件名

-l 查询多文件时只输出包含匹配字符的文件名

-r 相当于--directories=recurse 遍历目录

-s 不显示不存在或无匹配文本的错误信息

-E 允许使用egrep扩展模式匹配

-o    表示“only-matching”,即“仅匹配”之意(获取匹配到的字符串)

-w --word-regexp 强制 PATTERN 仅完全匹配字词

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
实例 2:从文件中查找关键词
[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
实例 4:grep 不显示本身进程
[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
实例 6:输出非 u 开头的行内容
[root@bogon ~]# cat test1.txt | grep -v ^u
hnlinux
redhat
Redhat
linux
centos
实例 7:输出以 hat 结尾的行内容
[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
实例 8:显示当前目录下以.txt 结尾的文件中的所有包含每个字符至少有 7 个连续小写字符的字符串的行
[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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值