[TOC]
0x00 快速入门
描述: 不管对于那一门编程语言,字符串类型都是及其重要的,所以在学习编程语言后会发现近40%左右都与字符串有关,特别是PHP当然在Linux中的shell脚本开发也同样存在;所以下面主要是字符串搜索命令采用正则匹配的命令,都是在shell编程中比较常用的;
grep 命令
描述:grep(global search regular expression(RE) and print out the line
,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。
Tips:属于Linux三剑客之一(grep、sed、awk)
语法和参数:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37grep 【选项】"字符串" 文件名 #在文件中查找字符串
#参数选项
-a 不要忽略二进制数据。
-A <显示列数> 除了显示符合范本样式的那一行之外,并显示该行之后的内容。
-B <显示列数> 并显示该行之前的内容
-b 在显示符合范本样式的那一行之外,并显示该行之前的内容。
-c 计算符合范本样式的列数。
-C <显示列数>或-<显示列数> 除了显示符合范本样式的那一列之外,并显示该列之前后的内容。(中间开始上下列数)
-d <进行动作> 当指定要查找的是目录而非文件时,必须使用这项参数,否则grep命令将回报信息并停止动作。
-e, --regexp=PATTERN #指定字符串作为查找文件内容的范本样式。 (常用即模式通配符匹配)
-E, --extended-regexp #支持正则匹配 grep需要使用正则表达式进行匹配 Expgress reg。(常用扩展正则匹配)
-G, --basic-regexp #基础正则匹配
-P, --perl-regexp #使用perl正则进行匹配
-f <范本文件> 指定范本文件,其内容有一个或多个范本样式,让grep查找符合范本条件的文件内容,格式为每一列的范本样式。
-F 将范本样式视为固定字符串的列表。
-G 将范本样式视为普通的表示法来使用。
-h 在显示符合范本样式的那一列之前,不标示该列所属的文件名称。
-H 在显示符合范本样式的那一列之前,同时打印包括搜索字符串的文件。 (常用)
-i 忽略字符大小写的差别,因为Linux严格区分大小写(常用)
-l 列出文件内容符合指定的范本样式的文件名称。
-L 列出文件内容不符合指定的范本样式的文件名称。
-n 在显示符合范本样式的那一列之前,标示出该列的编号。
-q 不显示任何信息。
-R/-r 此参数的效果和指定“-d recurse”参数相同,递归搜索。(常用)
-s 不显示错误信息。
-v 反转查找,即搜索不包含字符串的文件 (显示除字符串的其他类容)。 (常用)
-w 只显示全字符合的列。
-x 只显示全列符合的列。
-y 此参数效果跟“-i”相同。
-Z 显示匹配的文件以及匹配字符
-o 只输出文件中匹配到的部分不会输出那一行,精确输出我想要的内容.(常用)
--color=auto # 标记匹配颜色选项
--include * # 包含文件名称
--exclude * # 排除文件名称
--exclude-from file # 排除指定文件
实际案例: WeiyiGeek.正则与递归1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43#示例1.grep常用参数选项
grep "match_pattern" file_name #命令会返回一个包含“match_pattern”的文本行
grep -q "test" filename #静默输出不会输出任何信息,如果命令运行成功返回0,失败则返回非0值。一般用于条件测试。
grep -v "/" test.jsp #反向查找显示(排查/字符的行)
grep -i "test" test.jsp #忽略大小写
# TEST
grep -c "text" file_name #统计文件或者文本中包含匹配字符串的行数 Tips:grep -c 要比 grep | wc -l
# 1
grep "text" -n file_name #输出包含匹配字符串的行数
echo this is a text line | grep -e "is" -e "line" -o #多个匹配样式
# is
# line
#也可以使用-f选项来匹配多个样式,在样式文件中逐行写出需要匹配的字符。
echo aaa bbb ccc ddd eee | grep -f patfile.txt -o
#示例2.在多个文件中查找
grep "match_pattern" file_1 file_2 file_3
grep "text" -n file_1 file_2
grep -l "text" file1 file2 file3 # 搜索多个文件并查找匹配文本在哪些文件中
#示例3.正则表达式匹配和精准输出-o
grep -E "[1-9]+" #或egrep "[1-9]+"
grep -v -E "^#" sshd.conf |
echo this is a test line. | grep -o -E "[a-z]+\."
line.
echo this is a test line. | egrep -o "[a-z]+\."
line.
#示例4.在多级目录中对文本进行递归搜索 -r
grep "text" . -r -n # .表示当前目录。
echo -e "a\nb\nc\na\nb\nc" | grep 'a' -A 0
a
--
a
# 静默验证字符串是否在指定文件中。
grep -Eqi "Ubuntu" /etc/issue
echo $?
# 静默验证当前bash是否为
ps -p $$ | grep -siq bash
echo $?
1 | #示例4.进阶使用 |
1 | # 示例5.打印出匹配文本之前或者之后的行 |

WeiyiGeek.grep-ABC
补充示例:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33# 示例6.grep采用perl正则元字符(环视功能),必须指定参数-P
echo "WeiyiWeiyiGeek Whoami" | grep -oP "Weiyi(?=WeiyiGeek)" #当后面接的字符串可以匹配出则显示,否则不显示
Weiyi
echo "WeiyiGeek Whoami" | grep -oP "(?=WeiyiGeek)Weiyi"
Weiyi
# 实例7.-o只输出匹配的perl正则元字符字符串
grep -Po '(?<=^ID=")\w+' /etc/os-release
grep -Po '500381200107070222|500108200311291522' /tmp/2023gkys.logs
# 示例8.查询某一时间段后的100行
grep -A 100 "$(date -d '-1 minute' '+%Y-%m-%d %H:%M')" studentcenter.log
# 示例9.统计那些人已经看了网页
cd /app/logs/StudentCenter && grep -E "21500140770323|21500113771228" info.2021-04-18.0.log | grep "yxmc=" | grep -oE "ksh=\d{14}" | sort | uniq -c
# 示例10.匹配url的正则表达式(指定目录或者指定文件)
grep -ohr -E "https?://[a-zA-Z0-9\.\/_&=@$%?~#-]*" ./folder
grep -oE '(https|http|ftp)?://[a-zA-Z0-9\.\/_&=@$%?~#-]*' demo.txt | grep -vE ".docx$|.pdf$|.jpg$|.gif$" | sort | uniq
# 示例11.递归查询某一目录下不存在指定字符串的文件
grep -L "pageid:" -R . | grep -E "md$"
# 示例12.匹配一个或者多个中文汉字匹配,参数-P支持perl正则匹配字符
grep -o -P '[\p{Han}]{0,}' weiyigeek.top.log
# 示例13.只显示指定条件匹配到的字符串,参数-P支持perl正则匹配字符
grep -o -P 'ksh=[0-9]{14}, xm=[\p{Han}]{0,3}, sfzh=[0-9xX]{18}' /tmp/weiyigeek.logs
# ksh=23500111132484, xm=张某, sfzh=500106300602113826
# 示例14.对象Java项目Spring中日志打印出字符串进行匹配
grep -w -oP "^\[2023-01-[0-9]{0,2} [0-9]{0,2}:[0-9]{0,2}:[0-9]{0,2}.[0-9]{0,3}\]|ksh=[0-9]{14}, xm=[\p{Han}]{0,}, sfzh=[0-9xX]{18}" /tmp/weiyigeek.logs | sed ':a;N;$!ba;s/]\n/] /g'
# [2023-01-29 21:43:56.485] ksh=23500111132484, xm=张某, sfzh=500102200402103222
Find命令与Grep命令的区别:
1)Find在系统中搜索的条件的文件名,如需要匹配,使用通配符匹配是完全匹配
.
2)Grep在文件中搜索符号的字符串,如需匹配,则使用正则表达式是包含匹配
。
egrep 命令
描述:grep 默认仅支持基础正则表达式(Base Regular Expression),如果要使用扩展性正则表达式(Extended Regular Expression),使用egrep命令实际上grep -E == egrep ,extended regular expression比basic regular expression的表达更规范。
- egrep用extended regular expression语法来解读的
- grep用basic regular expression 语法解读
使用的语法及参数可参照grep指令,与grep的不同点在于解读字符串的方法。
1 | # 语法 |
实际案例: WeiyiGeek.正则egrep案例1
2
3
4
5
6
7
8
9
10
11
12
13
14# 示例1.简单示例
$ egrep -n 'goo*d' regular_express.txt #{0,N}
$ egrep -n 'go+d' regular_express.txt #{1,0}
$ egrep -n 'go?d' regular_express.txt #{0,1}
$ egrep -n 'g(la|oo)d' regular_express.txt #也就是搜寻(glad)或 good 这两个字符串
$echo'AxyzxyzxyzxyzC'|egrep 'A(xyz)+C'
$echo'AxyzxyzxyzxyzC'|egrep 'A(xz)+C'
# 示例2.忽略大小写匹配
egrep -i '^(From|Subject|Date): ' email.txt
# 示例2.统计 18:05~18:10 时间段里面指定字符串的行数输出匹配的字符串(进行了过滤)
cd /app/logs/StudentCenter && egrep "18:(05|06|07|08|09|10)" info.2021-03-12.0.log | grep "cjxmc=总分" | egrep -o "sfzh=[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]" | sort -u | wc -l
# 合计: 2815+2736+2585+2639+2640+2574