linux上执行文本搜索通过有以下几个命令:

  • grep
  • egrep
  • fgrep

这几个命令作用类型, 以下以grep为例讲解:


一. grep语法

什么是grep根据模式,搜索文本,并将符合模式的文本行显示出来
什么是匹配模式 Pattern : 文本字符以及正则表达式的元字符组合而成的匹配条件

grep 一般用法:

grep [OPTIONS] PATTERN [FILE…]

-i :忽略大小写
--color :颜色突出显示
-v: 显示没有匹配到的行(反向匹配)
-o : 只显示被模式匹配到的字符串(一个字符串显示为一行)

  • :任意长度字符
    ?:任意单个字符
    []:
    [^]

二. 正则表达式

正则表达式: RE regular expression REGEXP

元字符:

. : 匹配任意单个字符
[] :匹配指定范围内的任意单个字符
[^]:匹配指定范围外的任意单个字符
: 取反

字符集合: (引用的时候还要加一个 [ ] )

[:digit:] 数字
[:lower:] 小写字母
[:upper:] 大写字母
[:punct:] 标点符号
[:space:] 空白字符
[:alpha:] 所有字母
[:alnum:] 所有数字和字母

匹配次数(贪婪模式:尽可能长的匹配):

* :匹配其前面的字符任意次
样例字符: a,b,ab,aab,acb,adb,anib
a*b :表示a 出现任意次 然后匹配个b ,所以上面能匹配的是,b,ab,aab
.* :匹配任意长度的任意字符
a.*b : 则表示匹配a开头b结尾的字符串,中间任意啥都行 . 表示任意字符,* 表示匹配 . 任意次。
\?: 匹配其前面的字符1次或0次
a\?b
\{m,n\}匹配其前面的字符至少m次,至多n次
说明:\是转义字符,避免被shell解析为命令行展开
.
(.*?) 专题
1、. 匹配任意除换行符“\n”外的字符;
2、表示匹配前一个字符0次或无限次;
3、?表示前边字符的0次或1次重复
4、+或
后跟?表示非贪婪匹配,即尽可能少的匹配,如*?重复任意次,但尽可能少重复;
5、 .? 表示匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。
.
如:a.
?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab和ab。
举例:
a{1,3}b 匹配ab,a出现至少1次,最多3次的字符 --> ab,aab,aaab
a.{1,3}b a和b之间出现任意字符,最少1个,最多3个

位置锚定:

^ : 锚定行首,此字符后面的任意内容必须出现在行首
$ : 锚定行尾,此字符前面的任意内容必须出现在行尾
^$: 空白行
\<或\b: 锚定词首,其后面的任意字符必须作为单词首部出现
\>或\b: 锚定词尾,其前面的任意字符必须作为单词的尾部出现

分组:
\(\)
(ab)* : ab作为一个整体,可以出现任意次

后向引用
\1:引用第一个左括号以及与之对应的右括号所包括的所有内容 (ab).\1
\2:引用第二个左括号以及与之对应的右括号所包括的所有内容 (ab).
\2
\3:引用第三个左括号以及与之对应的右括号所包括的所有内容 (ab).*\3

示例:
原始数据集:

《红楼梦》
《三国演义》
《水浒传》
《西游记》

需求: 将所有书名前后的“《”、“》”,分别替换为“【”、“】”

replace(r'《(.*?)》', r'【\1】',regex=True)

正则表达式的分类:

  • Basic REGEXP: 基本正则表达式
  • Extended REGEXP:扩展正则表达式。

基本正则:

.:
[]:
[^]:

次数匹配:

*:
?: 0或1次
{m,n} :至少m次,至多n次

锚定:

^:
$:
<,\b:
>,\b

分组:

():
\1,\2,\3…

三. grep 结合 正则表达式

grep: 使用基本正则表达式定义的模式来过滤文本的命令

-i:忽略带大写
-v:反向搜索
-o:只显示匹配到的字符串
–color:显色
-E:使用扩展正则表达式
-A #: 表示某一行匹配到了,其后面的#行也显示出来,每一组用 – 分隔
-B #: 表示某一行匹配到了,其前面的#行也显示出来,每一组用 – 分隔
-C #:表示某一行匹配到了,其上下的#行也显示出来,每一组用 – 分隔

扩展的正则表达式:

字符匹配:

. :任意单个字符
[]:指定范围内的单个字符
[^]: 指定范围外的单个字符

次数匹配:

*:匹配其前字符匹配任意次
?:匹配其前字符0次或1次
+:匹配其前字符至少1次
{m,n}:至少m次,至多n次 (不需要再使用 \ )

位置锚定:

^: 行首
$: 行尾
<,\b: 词首
>,\b:词尾

分组:

(): 分组
\1,\2,\3…
或者
|:or

grep 与 egrep的替换

grep -E = egrep

举例:


例1. 1-255的数字正则表达式:

\<[1-9|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]]\>

例2. 匹配IP

IPV4的判断:
5类: ABCDE 类
A:1-127
B:128-191
C:192-233

例3: 匹配数字与下划线

样例数据: test_data.txt
-------------------------------------------
  "ageLevel_中年_湖北_男性比例" -> "51.37%"
  "1234_武汉市_男性比例" -> "52.13%"
  "ageLevel_中年_湖北_女性比例" -> "48.63%"
  "2234_黄冈市_男性比例" -> "51.13%"
  "2234_黄冈市_女性比例" -> "48.87%"
  "3234_荆州市_男性比例" -> "53.13%"
  "4234_恩施市_男性比例" -> "54.13%"
  "5234_孝感市_男性比例" -> "49.13%"
-------------------------------------------

# 查找湖北省各市人群性别比例
## 如果是在Notepad++等比阿尼器中, 使用如下正则表达式:
>     查询弹出窗口框中输入: "^[[:digit:]]{4}" 进行查询

## 如果是在linux下:
## 匹配以"空格开头含有引号后跟一串数字"的字符, 如[  "1234_武汉市_男性比例" -> "52.13%"]
[root@localhost]#  cat test_data.txt | grep -A1  '^\s+"\d{4}_'
[root@localhost]#  redis-cli -h ${IP} -p ${PORT} -c -a ${PWD} --raw hgetall ${REDIS_KEY} | grep -A1 -E "^[[:digit:]]{4}"

关于 fgrep

不支持正则表达式( 执行速度快)

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐