grep,egrep,fgrep的区别
概述
grep是一个在 Unix-like 操作系统中用于使用正则表达式进行文本搜索和匹配的命令行工具。
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即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}" # 正确匹配