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)
  ...

egrepfgrep不是二进制文件,而是shell脚本。
PS: 在我的Fedora38中,提示egrepfgrep已被废弃。

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:~

查看脚本得知,egrepgrep -E,fgrepgrep -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}" # 正确匹配
posted @   BrevinZhang  阅读(156)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示