grep,egrep,fgrep的区别
概述
grep
是一个在 Unix-like 操作系统中用于使用正则表达式进行文本搜索和匹配的命令行工具。
从帮助文档中可知,grep的-E参数代表使用拓展正则表达式,-F参数表达模式被看成换行符分割的字符串。
root@343924b81214:/ grep --help
Usage: grep [OPTION]... PATTERN [FILE]...
Search for PATTERN in each FILE.
Example: grep -i 'hello world' menu.h main.c
Pattern selection and interpretation:
-E, --extended-regexp PATTERN is an extended regular expression
-F, --fixed-strings PATTERN is a set of newline-separated strings
-G, --basic-regexp PATTERN is a basic regular expression (default)
...
egrep
和fgrep
不是二进制文件,而是shell脚本。
PS: 在我的Fedora38
中,提示egrep
和fgrep
已被废弃。
root@localhost:~ cat /usr/bin/egrep
#!/usr/bin/sh
cmd=${0##*/}
echo "$cmd: warning: $cmd is obsolescent; using grep -E" >&2
exec grep -E "$@"
root@localhost:~ cat /usr/bin/fgrep
#!/usr/bin/sh
cmd=${0##*/}
echo "$cmd: warning: $cmd is obsolescent; using grep -F" >&2
exec grep -F "$@"
root@localhost:~ file /usr/bin/egrep /usr/bin/fgrep
/usr/bin/egrep: a /usr/bin/sh script, ASCII text executable
/usr/bin/fgrep: a /usr/bin/sh script, ASCII text executable
root@localhost:~
查看脚本得知,egrep
即grep -E
,fgrep
即grep -F
正则表达式是由正则表达式引擎实现的,Linux中主要由两种正则表达式引擎:
- POSIX基础正则表达式(base regular expression, BRE)引擎
- POSIX扩展正则表达式(extended regular expression, ERE)引擎
grep
grep
使用BRE引擎实现,包括如下正则表达式元字符
.
匹配任意单个字符,不包括换行符*
前面的字符出现{0,n}次。注意和通配符里的*
不一样,通配符里的*
代表任意长度的字符。^
锚定行首,字符必须出现在行首。或者配合[]
表达排除[]
内的字符,如[^a]
。$
锚定行尾,字符必须出现在行尾[]
字符组,字符在给定区间内,如[ade]
、[a-zA-Z0-9]
如果需要将正则表达式元字符当成普通字符匹配,则需要在它们前面加上反斜杠\
进行转义
案例
找到/etc目录下所有以.sh结尾的文件
find /etc -type f | grep "\.sh$"
egrep
egrep
使用ERE引擎实现,ERE在BRE的基础上添加了如下元字符
+
前面的字符出现{1,n}次?
前面的字符出现{0,1}次{m,n}
前面的字符出现{m,n}次|
a|b 匹配模式a或模式b()
表达式分组,括号内的部分视为一个整体。比如ab*
表示a后面的b出现{0,n}次,(ab)*
表示ab出现{0,n}次。
综上,ERE包含如下正则表达式元字符
.
、*
、?
、+
、()
、[]
、{}
、|
fgrep
在正常的 grep
命令中,匹配的模式是按照正则表达式来解释的,这意味着某些字符(如 .、*、?、+ 等)具有特殊含义。然而,有时候我们希望将模式视为普通的字符串,而不考虑它们是否包含正则表达式中的元字符。
使用 -F
选项时,grep
将把模式视为固定字符串,而不会解释其中的正则表达式元字符,这对于查找字符串字面值而不是正则表达式模式的情况非常有用。
案例1
假如需要匹配字符串2.5*4=10.0
,使用grep需要对元字符*
、.
进行转义
echo "2.5*4=10.0" | grep "2\.5\*4=10\.0"
使用fgrep则不需要
echo "2.5*4=10.0" | fgrep "2.5*4=10.0"
案例2
假如需要实现一个匹配电话号码的功能,因为fgrep
不能使用正则表达式元字符,所以不能实现这个功能
echo "18912349876" | fgrep "[0-9]{11}" # 错误
echo "18912349876" | fgrep "\[0-9\]\{11\}" # 错误
正确的做法是使用egrep
echo "18912349876" | egrep "[0-9]{11}" # 正确匹配
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)